Skip to content

Commit 4ba782a

Browse files
authored
introducing deneb changes and blobs to builder (#12477)
1 parent ceb1ad3 commit 4ba782a

37 files changed

+2195
-171
lines changed

api/client/builder/BUILD.bazel

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ go_library(
1111
importpath = "github.com/prysmaticlabs/prysm/v4/api/client/builder",
1212
visibility = ["//visibility:public"],
1313
deps = [
14+
"//config/fieldparams:go_default_library",
1415
"//consensus-types:go_default_library",
1516
"//consensus-types/blocks:go_default_library",
1617
"//consensus-types/interfaces:go_default_library",
1718
"//consensus-types/primitives:go_default_library",
1819
"//encoding/bytesutil:go_default_library",
19-
"//math:go_default_library",
2020
"//monitoring/tracing:go_default_library",
2121
"//network:go_default_library",
2222
"//network/authorization:go_default_library",
@@ -40,6 +40,7 @@ go_test(
4040
data = glob(["testdata/**"]),
4141
embed = [":go_default_library"],
4242
deps = [
43+
"//config/fieldparams:go_default_library",
4344
"//config/params:go_default_library",
4445
"//consensus-types/blocks:go_default_library",
4546
"//consensus-types/primitives:go_default_library",

api/client/builder/bid.go

+100-9
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
package builder
22

33
import (
4-
"math/big"
5-
64
"github.com/pkg/errors"
75
ssz "github.com/prysmaticlabs/fastssz"
86
consensus_types "github.com/prysmaticlabs/prysm/v4/consensus-types"
97
"github.com/prysmaticlabs/prysm/v4/consensus-types/blocks"
108
"github.com/prysmaticlabs/prysm/v4/consensus-types/interfaces"
11-
"github.com/prysmaticlabs/prysm/v4/encoding/bytesutil"
12-
"github.com/prysmaticlabs/prysm/v4/math"
9+
enginev1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
1310
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
1411
"github.com/prysmaticlabs/prysm/v4/runtime/version"
1512
)
@@ -25,6 +22,7 @@ type SignedBid interface {
2522
// Bid is an interface describing the method set of a builder bid.
2623
type Bid interface {
2724
Header() (interfaces.ExecutionData, error)
25+
BlindedBlobsBundle() (*enginev1.BlindedBlobsBundle, error)
2826
Value() []byte
2927
Pubkey() []byte
3028
Version() int
@@ -117,6 +115,11 @@ func (b builderBid) Header() (interfaces.ExecutionData, error) {
117115
return blocks.WrappedExecutionPayloadHeader(b.p.Header)
118116
}
119117

118+
// BlindedBlobsBundle --
119+
func (b builderBid) BlindedBlobsBundle() (*enginev1.BlindedBlobsBundle, error) {
120+
return nil, errors.New("blinded blobs bundle not available before Deneb")
121+
}
122+
120123
// Version --
121124
func (b builderBid) Version() int {
122125
return version.Bellatrix
@@ -162,12 +165,13 @@ func WrappedBuilderBidCapella(p *ethpb.BuilderBidCapella) (Bid, error) {
162165

163166
// Header returns the execution data interface.
164167
func (b builderBidCapella) Header() (interfaces.ExecutionData, error) {
165-
if b.p == nil {
166-
return nil, errors.New("builder bid is nil")
167-
}
168168
// We have to convert big endian to little endian because the value is coming from the execution layer.
169-
v := big.NewInt(0).SetBytes(bytesutil.ReverseByteOrder(b.p.Value))
170-
return blocks.WrappedExecutionPayloadHeaderCapella(b.p.Header, math.WeiToGwei(v))
169+
return blocks.WrappedExecutionPayloadHeaderCapella(b.p.Header, blocks.PayloadValueToGwei(b.p.Value))
170+
}
171+
172+
// BlindedBlobsBundle --
173+
func (b builderBidCapella) BlindedBlobsBundle() (*enginev1.BlindedBlobsBundle, error) {
174+
return nil, errors.New("blinded blobs bundle not available before Deneb")
171175
}
172176

173177
// Version --
@@ -199,3 +203,90 @@ func (b builderBidCapella) HashTreeRoot() ([32]byte, error) {
199203
func (b builderBidCapella) HashTreeRootWith(hh *ssz.Hasher) error {
200204
return b.p.HashTreeRootWith(hh)
201205
}
206+
207+
type builderBidDeneb struct {
208+
p *ethpb.BuilderBidDeneb
209+
}
210+
211+
// WrappedBuilderBidDeneb is a constructor which wraps a protobuf bid into an interface.
212+
func WrappedBuilderBidDeneb(p *ethpb.BuilderBidDeneb) (Bid, error) {
213+
w := builderBidDeneb{p: p}
214+
if w.IsNil() {
215+
return nil, consensus_types.ErrNilObjectWrapped
216+
}
217+
return w, nil
218+
}
219+
220+
// Version --
221+
func (b builderBidDeneb) Version() int {
222+
return version.Deneb
223+
}
224+
225+
// Value --
226+
func (b builderBidDeneb) Value() []byte {
227+
return b.p.Value
228+
}
229+
230+
// Pubkey --
231+
func (b builderBidDeneb) Pubkey() []byte {
232+
return b.p.Pubkey
233+
}
234+
235+
// IsNil --
236+
func (b builderBidDeneb) IsNil() bool {
237+
return b.p == nil
238+
}
239+
240+
// HashTreeRoot --
241+
func (b builderBidDeneb) HashTreeRoot() ([32]byte, error) {
242+
return b.p.HashTreeRoot()
243+
}
244+
245+
// HashTreeRootWith --
246+
func (b builderBidDeneb) HashTreeRootWith(hh *ssz.Hasher) error {
247+
return b.p.HashTreeRootWith(hh)
248+
}
249+
250+
// Header --
251+
func (b builderBidDeneb) Header() (interfaces.ExecutionData, error) {
252+
// We have to convert big endian to little endian because the value is coming from the execution layer.
253+
return blocks.WrappedExecutionPayloadHeaderDeneb(b.p.Header, blocks.PayloadValueToGwei(b.p.Value))
254+
}
255+
256+
// BlindedBlobsBundle --
257+
func (b builderBidDeneb) BlindedBlobsBundle() (*enginev1.BlindedBlobsBundle, error) {
258+
return b.p.BlindedBlobsBundle, nil
259+
}
260+
261+
type signedBuilderBidDeneb struct {
262+
p *ethpb.SignedBuilderBidDeneb
263+
}
264+
265+
// WrappedSignedBuilderBidDeneb is a constructor which wraps a protobuf signed bit into an interface.
266+
func WrappedSignedBuilderBidDeneb(p *ethpb.SignedBuilderBidDeneb) (SignedBid, error) {
267+
w := signedBuilderBidDeneb{p: p}
268+
if w.IsNil() {
269+
return nil, consensus_types.ErrNilObjectWrapped
270+
}
271+
return w, nil
272+
}
273+
274+
// Message --
275+
func (b signedBuilderBidDeneb) Message() (Bid, error) {
276+
return WrappedBuilderBidDeneb(b.p.Message)
277+
}
278+
279+
// Signature --
280+
func (b signedBuilderBidDeneb) Signature() []byte {
281+
return b.p.Signature
282+
}
283+
284+
// Version --
285+
func (b signedBuilderBidDeneb) Version() int {
286+
return version.Deneb
287+
}
288+
289+
// IsNil --
290+
func (b signedBuilderBidDeneb) IsNil() bool {
291+
return b.p == nil
292+
}

api/client/builder/client.go

+69-18
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/prysmaticlabs/prysm/v4/monitoring/tracing"
2020
"github.com/prysmaticlabs/prysm/v4/network"
2121
"github.com/prysmaticlabs/prysm/v4/network/authorization"
22+
v1 "github.com/prysmaticlabs/prysm/v4/proto/engine/v1"
2223
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
2324
"github.com/prysmaticlabs/prysm/v4/runtime/version"
2425
log "github.com/sirupsen/logrus"
@@ -86,7 +87,7 @@ type BuilderClient interface {
8687
NodeURL() string
8788
GetHeader(ctx context.Context, slot primitives.Slot, parentHash [32]byte, pubkey [48]byte) (SignedBid, error)
8889
RegisterValidator(ctx context.Context, svr []*ethpb.SignedValidatorRegistrationV1) error
89-
SubmitBlindedBlock(ctx context.Context, sb interfaces.ReadOnlySignedBeaconBlock) (interfaces.ExecutionData, error)
90+
SubmitBlindedBlock(ctx context.Context, sb interfaces.ReadOnlySignedBeaconBlock, blobs []*ethpb.SignedBlindedBlobSidecar) (interfaces.ExecutionData, *v1.BlobsBundle, error)
9091
Status(ctx context.Context) error
9192
}
9293

@@ -220,6 +221,16 @@ func (c *Client) GetHeader(ctx context.Context, slot primitives.Slot, parentHash
220221
return nil, errors.Wrapf(err, "error unmarshaling the builder GetHeader response, using slot=%d, parentHash=%#x, pubkey=%#x", slot, parentHash, pubkey)
221222
}
222223
switch strings.ToLower(v.Version) {
224+
case strings.ToLower(version.String(version.Deneb)):
225+
hr := &ExecHeaderResponseDeneb{}
226+
if err := json.Unmarshal(hb, hr); err != nil {
227+
return nil, errors.Wrapf(err, "error unmarshaling the builder GetHeader response, using slot=%d, parentHash=%#x, pubkey=%#x", slot, parentHash, pubkey)
228+
}
229+
p, err := hr.ToProto()
230+
if err != nil {
231+
return nil, errors.Wrapf(err, "could not extract proto message from header")
232+
}
233+
return WrappedSignedBuilderBidDeneb(p)
223234
case strings.ToLower(version.String(version.Capella)):
224235
hr := &ExecHeaderResponseCapella{}
225236
if err := json.Unmarshal(hb, hr); err != nil {
@@ -274,20 +285,20 @@ func (c *Client) RegisterValidator(ctx context.Context, svr []*ethpb.SignedValid
274285

275286
// SubmitBlindedBlock calls the builder API endpoint that binds the validator to the builder and submits the block.
276287
// The response is the full execution payload used to create the blinded block.
277-
func (c *Client) SubmitBlindedBlock(ctx context.Context, sb interfaces.ReadOnlySignedBeaconBlock) (interfaces.ExecutionData, error) {
288+
func (c *Client) SubmitBlindedBlock(ctx context.Context, sb interfaces.ReadOnlySignedBeaconBlock, blobs []*ethpb.SignedBlindedBlobSidecar) (interfaces.ExecutionData, *v1.BlobsBundle, error) {
278289
if !sb.IsBlinded() {
279-
return nil, errNotBlinded
290+
return nil, nil, errNotBlinded
280291
}
281292
switch sb.Version() {
282293
case version.Bellatrix:
283294
psb, err := sb.PbBlindedBellatrixBlock()
284295
if err != nil {
285-
return nil, errors.Wrapf(err, "could not get protobuf block")
296+
return nil, nil, errors.Wrapf(err, "could not get protobuf block")
286297
}
287298
b := &SignedBlindedBeaconBlockBellatrix{SignedBlindedBeaconBlockBellatrix: psb}
288299
body, err := json.Marshal(b)
289300
if err != nil {
290-
return nil, errors.Wrap(err, "error encoding the SignedBlindedBeaconBlockBellatrix value body in SubmitBlindedBlock")
301+
return nil, nil, errors.Wrap(err, "error encoding the SignedBlindedBeaconBlockBellatrix value body in SubmitBlindedBlock")
291302
}
292303

293304
versionOpt := func(r *http.Request) {
@@ -296,29 +307,33 @@ func (c *Client) SubmitBlindedBlock(ctx context.Context, sb interfaces.ReadOnlyS
296307
rb, err := c.do(ctx, http.MethodPost, postBlindedBeaconBlockPath, bytes.NewBuffer(body), versionOpt)
297308

298309
if err != nil {
299-
return nil, errors.Wrap(err, "error posting the SignedBlindedBeaconBlockBellatrix to the builder api")
310+
return nil, nil, errors.Wrap(err, "error posting the SignedBlindedBeaconBlockBellatrix to the builder api")
300311
}
301312
ep := &ExecPayloadResponse{}
302313
if err := json.Unmarshal(rb, ep); err != nil {
303-
return nil, errors.Wrap(err, "error unmarshaling the builder SubmitBlindedBlock response")
314+
return nil, nil, errors.Wrap(err, "error unmarshaling the builder SubmitBlindedBlock response")
304315
}
305316
if strings.ToLower(ep.Version) != version.String(version.Bellatrix) {
306-
return nil, errors.New("not a bellatrix payload")
317+
return nil, nil, errors.New("not a bellatrix payload")
307318
}
308319
p, err := ep.ToProto()
309320
if err != nil {
310-
return nil, errors.Wrapf(err, "could not extract proto message from payload")
321+
return nil, nil, errors.Wrapf(err, "could not extract proto message from payload")
311322
}
312-
return blocks.WrappedExecutionPayload(p)
323+
payload, err := blocks.WrappedExecutionPayload(p)
324+
if err != nil {
325+
return nil, nil, errors.Wrapf(err, "could not wrap execution payload in interface")
326+
}
327+
return payload, nil, nil
313328
case version.Capella:
314329
psb, err := sb.PbBlindedCapellaBlock()
315330
if err != nil {
316-
return nil, errors.Wrapf(err, "could not get protobuf block")
331+
return nil, nil, errors.Wrapf(err, "could not get protobuf block")
317332
}
318333
b := &SignedBlindedBeaconBlockCapella{SignedBlindedBeaconBlockCapella: psb}
319334
body, err := json.Marshal(b)
320335
if err != nil {
321-
return nil, errors.Wrap(err, "error encoding the SignedBlindedBeaconBlockCapella value body in SubmitBlindedBlockCapella")
336+
return nil, nil, errors.Wrap(err, "error encoding the SignedBlindedBeaconBlockCapella value body in SubmitBlindedBlockCapella")
322337
}
323338

324339
versionOpt := func(r *http.Request) {
@@ -327,22 +342,58 @@ func (c *Client) SubmitBlindedBlock(ctx context.Context, sb interfaces.ReadOnlyS
327342
rb, err := c.do(ctx, http.MethodPost, postBlindedBeaconBlockPath, bytes.NewBuffer(body), versionOpt)
328343

329344
if err != nil {
330-
return nil, errors.Wrap(err, "error posting the SignedBlindedBeaconBlockCapella to the builder api")
345+
return nil, nil, errors.Wrap(err, "error posting the SignedBlindedBeaconBlockCapella to the builder api")
331346
}
332347
ep := &ExecPayloadResponseCapella{}
333348
if err := json.Unmarshal(rb, ep); err != nil {
334-
return nil, errors.Wrap(err, "error unmarshaling the builder SubmitBlindedBlockCapella response")
349+
return nil, nil, errors.Wrap(err, "error unmarshaling the builder SubmitBlindedBlockCapella response")
335350
}
336351
if strings.ToLower(ep.Version) != version.String(version.Capella) {
337-
return nil, errors.New("not a capella payload")
352+
return nil, nil, errors.New("not a capella payload")
338353
}
339354
p, err := ep.ToProto()
340355
if err != nil {
341-
return nil, errors.Wrapf(err, "could not extract proto message from payload")
356+
return nil, nil, errors.Wrapf(err, "could not extract proto message from payload")
357+
}
358+
payload, err := blocks.WrappedExecutionPayloadCapella(p, 0)
359+
if err != nil {
360+
return nil, nil, errors.Wrapf(err, "could not wrap execution payload in interface")
361+
}
362+
return payload, nil, nil
363+
case version.Deneb:
364+
psb, err := sb.PbBlindedDenebBlock()
365+
if err != nil {
366+
return nil, nil, errors.Wrapf(err, "could not get protobuf block")
367+
}
368+
369+
b := &ethpb.SignedBlindedBeaconBlockAndBlobsDeneb{Block: psb, Blobs: blobs}
370+
body, err := json.Marshal(b)
371+
if err != nil {
372+
return nil, nil, errors.Wrap(err, "error encoding the SignedBlindedBeaconBlockDeneb value body in SubmitBlindedBlockDeneb")
373+
}
374+
375+
versionOpt := func(r *http.Request) {
376+
r.Header.Add("Eth-Consensus-Version", version.String(version.Deneb))
377+
}
378+
rb, err := c.do(ctx, http.MethodPost, postBlindedBeaconBlockPath, bytes.NewBuffer(body), versionOpt)
379+
ep := &ExecPayloadResponseDeneb{}
380+
if err := json.Unmarshal(rb, ep); err != nil {
381+
return nil, nil, errors.Wrap(err, "error unmarshaling the builder SubmitBlindedBlockDeneb response")
382+
}
383+
if strings.ToLower(ep.Version) != version.String(version.Deneb) {
384+
return nil, nil, errors.New("not a deneb payload")
385+
}
386+
p, blobBundle, err := ep.ToProto()
387+
if err != nil {
388+
return nil, nil, errors.Wrapf(err, "could not extract proto message from payload")
389+
}
390+
payload, err := blocks.WrappedExecutionPayloadDeneb(p, 0)
391+
if err != nil {
392+
return nil, nil, errors.Wrapf(err, "could not wrap execution payload in interface")
342393
}
343-
return blocks.WrappedExecutionPayloadCapella(p, 0)
394+
return payload, blobBundle, nil
344395
default:
345-
return nil, fmt.Errorf("unsupported block version %s", version.String(sb.Version()))
396+
return nil, nil, fmt.Errorf("unsupported block version %s", version.String(sb.Version()))
346397
}
347398
}
348399

0 commit comments

Comments
 (0)