From e3f9f87da664ad36bee800817453f3b0ca4f6164 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Thu, 19 May 2022 18:49:27 -0500 Subject: [PATCH 01/21] builder api client --- api/client/builder/BUILD.bazel | 39 ++ api/client/builder/client.go | 206 ++++++++ api/client/builder/client_test.go | 316 ++++++++++++ api/client/builder/errors.go | 10 + api/client/builder/types.go | 549 +++++++++++++++++++++ api/client/builder/types_test.go | 621 ++++++++++++++++++++++++ proto/prysm/v1alpha1/beacon_block.pb.go | 397 +++++++++++++-- proto/prysm/v1alpha1/beacon_block.proto | 23 + 8 files changed, 2130 insertions(+), 31 deletions(-) create mode 100644 api/client/builder/BUILD.bazel create mode 100644 api/client/builder/client.go create mode 100644 api/client/builder/client_test.go create mode 100644 api/client/builder/errors.go create mode 100644 api/client/builder/types.go create mode 100644 api/client/builder/types_test.go diff --git a/api/client/builder/BUILD.bazel b/api/client/builder/BUILD.bazel new file mode 100644 index 000000000000..9790f4ac6e5b --- /dev/null +++ b/api/client/builder/BUILD.bazel @@ -0,0 +1,39 @@ +load("@prysm//tools/go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = [ + "client.go", + "errors.go", + "types.go", + ], + importpath = "github.com/prysmaticlabs/prysm/api/client/builder", + visibility = ["//visibility:public"], + deps = [ + "//consensus-types/primitives:go_default_library", + "//proto/engine/v1:go_default_library", + "//proto/prysm/v1alpha1:go_default_library", + "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", + "@com_github_pkg_errors//:go_default_library", + "@com_github_sirupsen_logrus//:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = [ + "client_test.go", + "types_test.go", + ], + embed = [":go_default_library"], + deps = [ + "//config/fieldparams:go_default_library", + "//consensus-types/primitives:go_default_library", + "//encoding/bytesutil:go_default_library", + "//proto/engine/v1:go_default_library", + "//proto/prysm/v1alpha1:go_default_library", + "//testing/require:go_default_library", + "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", + "@com_github_prysmaticlabs_go_bitfield//:go_default_library", + ], +) diff --git a/api/client/builder/client.go b/api/client/builder/client.go new file mode 100644 index 000000000000..25ecccb4ecf0 --- /dev/null +++ b/api/client/builder/client.go @@ -0,0 +1,206 @@ +package builder + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net" + "net/http" + "net/url" + "text/template" + "time" + + v1 "github.com/prysmaticlabs/prysm/proto/engine/v1" + ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" + + "github.com/pkg/errors" + types "github.com/prysmaticlabs/prysm/consensus-types/primitives" + log "github.com/sirupsen/logrus" +) + +const ( + getExecHeaderPath = "/eth/v1/builder/header/{{.Slot}}/{{.ParentHash}}/{{.Pubkey}}" + getStatus = "/eth/v1/builder/status" + postBlindedBeaconBlockPath = "/eth/v1/builder/blinded_blocks" + postRegisterValidatorPath = "/eth/v1/builder/validators" +) + +var ErrMalformedHostname = errors.New("hostname must include port, separated by one colon, like example.com:3500") + +// ClientOpt is a functional option for the Client type (http.Client wrapper) +type ClientOpt func(*Client) + +// WithTimeout sets the .Timeout attribute of the wrapped http.Client. +func WithTimeout(timeout time.Duration) ClientOpt { + return func(c *Client) { + c.hc.Timeout = timeout + } +} + +// Client provides a collection of helper methods for calling the Eth Beacon Node API endpoints. +type Client struct { + hc *http.Client + baseURL *url.URL +} + +// NewClient constructs a new client with the provided options (ex WithTimeout). +// `host` is the base host + port used to construct request urls. This value can be +// a URL string, or NewClient will assume an http endpoint if just `host:port` is used. +func NewClient(host string, opts ...ClientOpt) (*Client, error) { + u, err := urlForHost(host) + if err != nil { + return nil, err + } + c := &Client{ + hc: &http.Client{}, + baseURL: u, + } + for _, o := range opts { + o(c) + } + return c, nil +} + +func urlForHost(h string) (*url.URL, error) { + // try to parse as url (being permissive) + u, err := url.Parse(h) + if err == nil && u.Host != "" { + return u, nil + } + // try to parse as host:port + host, port, err := net.SplitHostPort(h) + if err != nil { + return nil, ErrMalformedHostname + } + return &url.URL{Host: fmt.Sprintf("%s:%s", host, port), Scheme: "http"}, nil +} + +// NodeURL returns a human-readable string representation of the beacon node base url. +func (c *Client) NodeURL() string { + return c.baseURL.String() +} + +type reqOption func(*http.Request) + +// do is a generic, opinionated GET function to reduce boilerplate amongst the getters in this packageapi/client/builder/types.go. +func (c *Client) do(ctx context.Context, method string, path string, body io.Reader, opts ...reqOption) ([]byte, error) { + u := c.baseURL.ResolveReference(&url.URL{Path: path}) + log.Printf("requesting %s", u.String()) + req, err := http.NewRequestWithContext(ctx, method, u.String(), body) + if err != nil { + return nil, err + } + for _, o := range opts { + o(req) + } + r, err := c.hc.Do(req) + if err != nil { + return nil, err + } + defer func() { + err = r.Body.Close() + }() + if r.StatusCode != http.StatusOK { + return nil, non200Err(r) + } + b, err := io.ReadAll(r.Body) + if err != nil { + return nil, errors.Wrap(err, "error reading http response body from GetBlock") + } + return b, nil +} + +var execHeaderTemplate = template.Must(template.New("").Parse(getExecHeaderPath)) + +func execHeaderPath(slot types.Slot, parentHash [32]byte, pubkey [48]byte) (string, error) { + v := struct { + Slot types.Slot + ParentHash string + Pubkey string + }{ + Slot: slot, + ParentHash: fmt.Sprintf("%#x", parentHash), + Pubkey: fmt.Sprintf("%#x", pubkey), + } + b := bytes.NewBuffer(nil) + err := execHeaderTemplate.Execute(b, v) + if err != nil { + return "", errors.Wrapf(err, "error rendering exec header template with slot=%d, parentHash=%#x, pubkey=%#x", slot, parentHash, pubkey) + } + return b.String(), nil +} + +// GetHeader is used by a proposing validator to request an ExecutionPayloadHeader from the Builder node. +func (c *Client) GetHeader(ctx context.Context, slot types.Slot, parentHash [32]byte, pubkey [48]byte) (*ethpb.SignedBuilderBid, error) { + path, err := execHeaderPath(slot, parentHash, pubkey) + if err != nil { + return nil, err + } + hb, err := c.do(ctx, http.MethodGet, path, nil) + if err != nil { + return nil, err + } + hr := &ExecHeaderResponse{} + if err := json.Unmarshal(hb, hr); err != nil { + return nil, errors.Wrapf(err, "error unmarshaling the builder GetHeader response, using slot=%d, parentHash=%#x, pubkey=%#x", slot, parentHash, pubkey) + } + return hr.ToProto() +} + +// RegisterValidator encodes the SignedValidatorRegistrationV1 message to json (including hex-encoding the byte +// fields with 0x prefixes) and posts to the builder validator registration endpoint. +func (c *Client) RegisterValidator(ctx context.Context, svr *ethpb.SignedValidatorRegistrationV1) error { + v := &SignedValidatorRegistration{SignedValidatorRegistrationV1: svr} + body, err := json.Marshal(v) + if err != nil { + return errors.Wrap(err, "error encoding the SignedValidatorRegistration value body in RegisterValidator") + } + _, err = c.do(ctx, http.MethodPost, postRegisterValidatorPath, bytes.NewBuffer(body)) + return err +} + +// SubmitBlindedBlock calls the builder API endpoint that binds the validator to the builder and submits the block. +// The response is the full ExecutionPayload used to create the blinded block. +func (c *Client) SubmitBlindedBlock(ctx context.Context, sb *ethpb.SignedBlindedBeaconBlockBellatrix) (*v1.ExecutionPayload, error) { + v := &SignedBlindedBeaconBlockBellatrix{SignedBlindedBeaconBlockBellatrix: sb} + body, err := json.Marshal(v) + if err != nil { + return nil, errors.Wrap(err, "error encoding the SignedBlindedBeaconBlockBellatrix value body in SubmitBlindedBlock") + } + rb, err := c.do(ctx, http.MethodPost, postBlindedBeaconBlockPath, bytes.NewBuffer(body)) + if err != nil { + return nil, errors.Wrap(err, "error posting the SignedBlindedBeaconBlockBellatrix to the builder api") + } + ep := &ExecPayloadResponse{} + if err := json.Unmarshal(rb, ep); err != nil { + return nil, errors.Wrap(err, "error unmarshaling the builder SubmitBlindedBlock response") + } + return ep.ToProto() +} + +// Status asks the remote builder server for a health check. A response of 200 with an empty body is the success/healthy +// response, and an error response may have an error message. This method will return a nil value for error in the +// happy path, and an error with information about the server response body for a non-200 response. +func (c *Client) Status(ctx context.Context) error { + _, err := c.do(ctx, http.MethodGet, getStatus, nil) + return err +} + +func non200Err(response *http.Response) error { + bodyBytes, err := io.ReadAll(response.Body) + var body string + if err != nil { + body = "(Unable to read response body.)" + } else { + body = "response body:\n" + string(bodyBytes) + } + msg := fmt.Sprintf("code=%d, url=%s, body=%s", response.StatusCode, response.Request.URL, body) + switch response.StatusCode { + case 404: + return errors.Wrap(ErrNotFound, msg) + default: + return errors.Wrap(ErrNotOK, msg) + } +} diff --git a/api/client/builder/client_test.go b/api/client/builder/client_test.go new file mode 100644 index 000000000000..612a22f13f77 --- /dev/null +++ b/api/client/builder/client_test.go @@ -0,0 +1,316 @@ +package builder + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" + "strconv" + "testing" + + "github.com/prysmaticlabs/go-bitfield" + fieldparams "github.com/prysmaticlabs/prysm/config/fieldparams" + types "github.com/prysmaticlabs/prysm/consensus-types/primitives" + "github.com/prysmaticlabs/prysm/encoding/bytesutil" + eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/testing/require" +) + +type roundtrip func(*http.Request) (*http.Response, error) + +func (fn roundtrip) RoundTrip(r *http.Request) (*http.Response, error) { + return fn(r) +} + +func TestClient_Status(t *testing.T) { + ctx := context.Background() + statusPath := "/eth/v1/builder/status" + hc := &http.Client{ + Transport: roundtrip(func(r *http.Request) (*http.Response, error) { + defer func() { + if r.Body == nil { + return + } + require.NoError(t, r.Body.Close()) + }() + require.Equal(t, statusPath, r.URL.Path) + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(bytes.NewBuffer(nil)), + Request: r.Clone(ctx), + }, nil + }), + } + c := &Client{ + hc: hc, + baseURL: &url.URL{Host: "localhost:3500", Scheme: "http"}, + } + require.NoError(t, c.Status(ctx)) + hc = &http.Client{ + Transport: roundtrip(func(r *http.Request) (*http.Response, error) { + defer func() { + if r.Body == nil { + return + } + require.NoError(t, r.Body.Close()) + }() + require.Equal(t, statusPath, r.URL.Path) + return &http.Response{ + StatusCode: http.StatusInternalServerError, + Body: io.NopCloser(bytes.NewBuffer(nil)), + Request: r.Clone(ctx), + }, nil + }), + } + c = &Client{ + hc: hc, + baseURL: &url.URL{Host: "localhost:3500", Scheme: "http"}, + } + require.ErrorIs(t, c.Status(ctx), ErrNotOK) +} + +func TestClient_RegisterValidator(t *testing.T) { + ctx := context.Background() + expectedBody := `{"message":{"fee_recipient":"0x0000000000000000000000000000000000000000","gas_limit":"23","timestamp":"42","pubkey":"0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a"}}` + expectedPath := "/eth/v1/builder/validators" + hc := &http.Client{ + Transport: roundtrip(func(r *http.Request) (*http.Response, error) { + body, err := io.ReadAll(r.Body) + defer func() { + require.NoError(t, r.Body.Close()) + }() + require.NoError(t, err) + require.Equal(t, expectedBody, string(body)) + require.Equal(t, expectedPath, r.URL.Path) + require.Equal(t, http.MethodPost, r.Method) + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(bytes.NewBuffer(nil)), + Request: r.Clone(ctx), + }, nil + }), + } + c := &Client{ + hc: hc, + baseURL: &url.URL{Host: "localhost:3500", Scheme: "http"}, + } + reg := ð.SignedValidatorRegistrationV1{ + Message: ð.ValidatorRegistrationV1{ + FeeRecipient: ezDecode(t, fieldparams.EthBurnAddressHex), + GasLimit: 23, + Timestamp: 42, + Pubkey: ezDecode(t, "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a"), + }, + } + require.NoError(t, c.RegisterValidator(ctx, reg)) +} + +func TestClient_GetHeader(t *testing.T) { + ctx := context.Background() + expectedPath := "/eth/v1/builder/header/23/0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2/0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a" + hc := &http.Client{ + Transport: roundtrip(func(r *http.Request) (*http.Response, error) { + require.Equal(t, expectedPath, r.URL.Path) + return &http.Response{ + StatusCode: http.StatusInternalServerError, + Body: io.NopCloser(bytes.NewBuffer(nil)), + Request: r.Clone(ctx), + }, nil + }), + } + c := &Client{ + hc: hc, + baseURL: &url.URL{Host: "localhost:3500", Scheme: "http"}, + } + var slot types.Slot = 23 + parentHash := ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + pubkey := ezDecode(t, "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a") + _, err := c.GetHeader(ctx, slot, bytesutil.ToBytes32(parentHash), bytesutil.ToBytes48(pubkey)) + require.ErrorIs(t, err, ErrNotOK) + + hc = &http.Client{ + Transport: roundtrip(func(r *http.Request) (*http.Response, error) { + require.Equal(t, expectedPath, r.URL.Path) + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(bytes.NewBufferString(testExampleHeaderResponse)), + Request: r.Clone(ctx), + }, nil + }), + } + c = &Client{ + hc: hc, + baseURL: &url.URL{Host: "localhost:3500", Scheme: "http"}, + } + h, err := c.GetHeader(ctx, slot, bytesutil.ToBytes32(parentHash), bytesutil.ToBytes48(pubkey)) + require.NoError(t, err) + expectedSig := ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505") + require.Equal(t, true, bytes.Equal(expectedSig, h.Signature)) + expectedTxRoot := ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.Equal(t, true, bytes.Equal(expectedTxRoot, h.Message.Header.TransactionsRoot)) +} + +func TestSubmitBlindedBlock(t *testing.T) { + ctx := context.Background() + hc := &http.Client{ + Transport: roundtrip(func(r *http.Request) (*http.Response, error) { + require.Equal(t, postBlindedBeaconBlockPath, r.URL.Path) + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(bytes.NewBufferString(testExampleExecutionPayload)), + Request: r.Clone(ctx), + }, nil + }), + } + c := &Client{ + hc: hc, + baseURL: &url.URL{Host: "localhost:3500", Scheme: "http"}, + } + sbbb := testSignedBlindedBeaconBlockBellatrix(t) + ep, err := c.SubmitBlindedBlock(ctx, sbbb) + require.NoError(t, err) + require.Equal(t, true, bytes.Equal(ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), ep.ParentHash)) +} + +func testSignedBlindedBeaconBlockBellatrix(t *testing.T) *eth.SignedBlindedBeaconBlockBellatrix { + return ð.SignedBlindedBeaconBlockBellatrix{ + Block: ð.BlindedBeaconBlockBellatrix{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Body: ð.BlindedBeaconBlockBodyBellatrix{ + RandaoReveal: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + Eth1Data: ð.Eth1Data{ + DepositRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + DepositCount: 1, + BlockHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Graffiti: ezDecode(t, "0xdeadbeefc0ffee"), + ProposerSlashings: []*eth.ProposerSlashing{ + { + Header_1: ð.SignedBeaconBlockHeader{ + Header: ð.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BodyRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + Header_2: ð.SignedBeaconBlockHeader{ + Header: ð.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BodyRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + }, + }, + AttesterSlashings: []*eth.AttesterSlashing{ + { + Attestation_1: ð.IndexedAttestation{ + AttestingIndices: []uint64{1}, + Data: ð.AttestationData{ + Slot: 1, + CommitteeIndex: 1, + BeaconBlockRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Source: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Target: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + Attestation_2: ð.IndexedAttestation{ + AttestingIndices: []uint64{1}, + Data: ð.AttestationData{ + Slot: 1, + CommitteeIndex: 1, + BeaconBlockRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Source: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Target: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + }, + }, + Attestations: []*eth.Attestation{ + { + AggregationBits: bitfield.Bitlist{0x01}, + Data: ð.AttestationData{ + Slot: 1, + CommitteeIndex: 1, + BeaconBlockRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Source: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Target: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + }, + Deposits: []*eth.Deposit{ + { + Proof: [][]byte{ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2")}, + Data: ð.Deposit_Data{ + PublicKey: ezDecode(t, "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a"), + WithdrawalCredentials: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Amount: 1, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + }, + }, + VoluntaryExits: []*eth.SignedVoluntaryExit{ + { + Exit: ð.VoluntaryExit{ + Epoch: 1, + ValidatorIndex: 1, + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + }, + SyncAggregate: ð.SyncAggregate{ + SyncCommitteeSignature: make([]byte, 48), + SyncCommitteeBits: bitfield.Bitvector512{0x01}, + }, + ExecutionPayloadHeader: ð.ExecutionPayloadHeader{ + ParentHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + FeeRecipient: ezDecode(t, "0xabcf8e0d4e9587369b2301d0790347320302cc09"), + StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + ReceiptsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + LogsBloom: ezDecode(t, "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + PrevRandao: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BlockNumber: 1, + GasLimit: 1, + GasUsed: 1, + Timestamp: 1, + ExtraData: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BaseFeePerGas: []byte(strconv.FormatUint(1, 10)), + BlockHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + TransactionsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + }, + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + } +} diff --git a/api/client/builder/errors.go b/api/client/builder/errors.go new file mode 100644 index 000000000000..a6ca3e5c21e0 --- /dev/null +++ b/api/client/builder/errors.go @@ -0,0 +1,10 @@ +package builder + +import "github.com/pkg/errors" + +// ErrNotOK is used to indicate when an HTTP request to the Beacon Node API failed with any non-2xx response code. +// More specific errors may be returned, but an error in reaction to a non-2xx response will always wrap ErrNotOK. +var ErrNotOK = errors.New("did not receive 2xx response from API") + +// ErrNotFound specifically means that a '404 - NOT FOUND' response was received from the API. +var ErrNotFound = errors.Wrap(ErrNotOK, "recv 404 NotFound response from API") diff --git a/api/client/builder/types.go b/api/client/builder/types.go new file mode 100644 index 000000000000..fe42f12cd1ac --- /dev/null +++ b/api/client/builder/types.go @@ -0,0 +1,549 @@ +package builder + +import ( + "encoding/json" + "fmt" + "math/big" + "strconv" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/pkg/errors" + v1 "github.com/prysmaticlabs/prysm/proto/engine/v1" + eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" +) + +type SignedValidatorRegistration struct { + *eth.SignedValidatorRegistrationV1 +} + +type ValidatorRegistration struct { + *eth.ValidatorRegistrationV1 +} + +func (r *SignedValidatorRegistration) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Message *ValidatorRegistration `json:"message,omitempty"` + Signature hexSlice `json:"signature,omitempty"` + }{ + Message: &ValidatorRegistration{r.Message}, + Signature: r.SignedValidatorRegistrationV1.Signature, + }) +} + +func (r *ValidatorRegistration) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + FeeRecipient hexSlice `json:"fee_recipient,omitempty"` + GasLimit string `json:"gas_limit,omitempty"` + Timestamp string `json:"timestamp,omitempty"` + Pubkey hexSlice `json:"pubkey,omitempty"` + *eth.ValidatorRegistrationV1 + }{ + FeeRecipient: r.FeeRecipient, + GasLimit: fmt.Sprintf("%d", r.GasLimit), + Timestamp: fmt.Sprintf("%d", r.Timestamp), + Pubkey: r.Pubkey, + ValidatorRegistrationV1: r.ValidatorRegistrationV1, + }) +} + +type hexSlice []byte + +func (hs hexSlice) MarshalText() ([]byte, error) { + return []byte(fmt.Sprintf("%#x", hs)), nil +} + +func (hs *hexSlice) UnmarshalText(t []byte) error { + decoded, err := hexutil.Decode(string(t)) + if err != nil { + return errors.Wrapf(err, "error unmarshaling text value %s", string(t)) + } + *hs = decoded + return nil +} + +type Uint256 struct { + *big.Int +} + +var errUnmarshalUint256Failed = errors.New("unable to UnmarshalText into a Uint256 value") + +func (s *Uint256) UnmarshalJSON(t []byte) error { + start := 0 + end := len(t) + if t[0] == '"' { + start += 1 + } + if t[end-1] == '"' { + end -= 1 + } + return s.UnmarshalText(t[start:end]) +} + +func (s *Uint256) UnmarshalText(t []byte) error { + if s.Int == nil { + s.Int = big.NewInt(0) + } + z, ok := s.SetString(string(t), 10) + if !ok { + return errors.Wrapf(errUnmarshalUint256Failed, "value=%s", string(t)) + } + s.Int = z + return nil +} + +func (s Uint256) MarshalText() ([]byte, error) { + return s.Bytes(), nil +} + +type Uint64String uint64 + +func (s *Uint64String) UnmarshalText(t []byte) error { + u, err := strconv.ParseUint(string(t), 10, 64) + *s = Uint64String(u) + return err +} + +func (s Uint64String) MarshalText() ([]byte, error) { + return []byte(fmt.Sprintf("%d", s)), nil +} + +type ExecHeaderResponse struct { + Version string `json:"version,omitempty"` + Data struct { + Signature hexSlice `json:"signature,omitempty"` + Message *BuilderBid `json:"message,omitempty"` + } `json:"data,omitempty"` +} + +func (ehr *ExecHeaderResponse) ToProto() (*eth.SignedBuilderBid, error) { + bb, err := ehr.Data.Message.ToProto() + if err != nil { + return nil, err + } + return ð.SignedBuilderBid{ + Message: bb, + Signature: ehr.Data.Signature, + }, nil +} + +func (bb *BuilderBid) ToProto() (*eth.BuilderBid, error) { + header, err := bb.Header.ToProto() + if err != nil { + return nil, err + } + return ð.BuilderBid{ + Header: header, + Value: bb.Value.Bytes(), + Pubkey: bb.Pubkey, + }, nil +} + +func (h *ExecutionPayloadHeader) ToProto() (*eth.ExecutionPayloadHeader, error) { + // TODO: it looks like BaseFeePerGas should probably be a uint + baseFeeHack := []byte(strconv.FormatUint(uint64(h.BaseFeePerGas), 10)) + return ð.ExecutionPayloadHeader{ + ParentHash: h.ParentHash, + FeeRecipient: h.FeeRecipient, + StateRoot: h.StateRoot, + ReceiptsRoot: h.ReceiptsRoot, + LogsBloom: h.LogsBloom, + PrevRandao: h.PrevRandao, + BlockNumber: uint64(h.BlockNumber), + GasLimit: uint64(h.GasLimit), + GasUsed: uint64(h.GasUsed), + Timestamp: uint64(h.Timestamp), + ExtraData: h.ExtraData, + BaseFeePerGas: baseFeeHack, + BlockHash: h.BlockHash, + TransactionsRoot: h.TransactionsRoot, + }, nil +} + +type BuilderBid struct { + Header *ExecutionPayloadHeader `json:"header,omitempty"` + Value Uint256 `json:"value,omitempty"` + Pubkey hexSlice `json:"pubkey,omitempty"` +} + +type ExecutionPayloadHeader struct { + ParentHash hexSlice `json:"parent_hash,omitempty"` + FeeRecipient hexSlice `json:"fee_recipient,omitempty"` + StateRoot hexSlice `json:"state_root,omitempty"` + ReceiptsRoot hexSlice `json:"receipts_root,omitempty"` + LogsBloom hexSlice `json:"logs_bloom,omitempty"` + PrevRandao hexSlice `json:"prev_randao,omitempty"` + BlockNumber Uint64String `json:"block_number,omitempty"` + GasLimit Uint64String `json:"gas_limit,omitempty"` + GasUsed Uint64String `json:"gas_used,omitempty"` + Timestamp Uint64String `json:"timestamp,omitempty"` + ExtraData hexSlice `json:"extra_data,omitempty"` + BaseFeePerGas Uint64String `json:"base_fee_per_gas,omitempty"` + BlockHash hexSlice `json:"block_hash,omitempty"` + TransactionsRoot hexSlice `json:"transactions_root,omitempty"` + *eth.ExecutionPayloadHeader +} + +func (h *ExecutionPayloadHeader) MarshalJSON() ([]byte, error) { + // TODO check this encoding and confirm bounds of values + bfpg, err := strconv.ParseUint(string(h.ExecutionPayloadHeader.BaseFeePerGas), 10, 64) + if err != nil { + return nil, err + } + type MarshalCaller ExecutionPayloadHeader + return json.Marshal(&MarshalCaller{ + ParentHash: h.ExecutionPayloadHeader.ParentHash, + FeeRecipient: h.ExecutionPayloadHeader.FeeRecipient, + StateRoot: h.ExecutionPayloadHeader.StateRoot, + ReceiptsRoot: h.ExecutionPayloadHeader.ReceiptsRoot, + LogsBloom: h.ExecutionPayloadHeader.LogsBloom, + PrevRandao: h.ExecutionPayloadHeader.PrevRandao, + BlockNumber: Uint64String(h.ExecutionPayloadHeader.BlockNumber), + GasLimit: Uint64String(h.ExecutionPayloadHeader.GasLimit), + GasUsed: Uint64String(h.ExecutionPayloadHeader.GasUsed), + Timestamp: Uint64String(h.ExecutionPayloadHeader.Timestamp), + ExtraData: h.ExecutionPayloadHeader.ExtraData, + BaseFeePerGas: Uint64String(bfpg), + BlockHash: h.ExecutionPayloadHeader.BlockHash, + TransactionsRoot: h.ExecutionPayloadHeader.TransactionsRoot, + }) +} + +type ExecPayloadResponse struct { + Version string `json:"version,omitempty"` + Data ExecutionPayload `json:"data,omitempty"` +} + +type ExecutionPayload struct { + ParentHash hexSlice `json:"parent_hash,omitempty"` + FeeRecipient hexSlice `json:"fee_recipient,omitempty"` + StateRoot hexSlice `json:"state_root,omitempty"` + ReceiptsRoot hexSlice `json:"receipts_root,omitempty"` + LogsBloom hexSlice `json:"logs_bloom,omitempty"` + PrevRandao hexSlice `json:"prev_randao,omitempty"` + BlockNumber Uint64String `json:"block_number,omitempty"` + GasLimit Uint64String `json:"gas_limit,omitempty"` + GasUsed Uint64String `json:"gas_used,omitempty"` + Timestamp Uint64String `json:"timestamp,omitempty"` + ExtraData hexSlice `json:"extra_data,omitempty"` + BaseFeePerGas Uint64String `json:"base_fee_per_gas,omitempty"` + BlockHash hexSlice `json:"block_hash,omitempty"` + Transactions []hexSlice `json:"transactions,omitempty"` +} + +func (r *ExecPayloadResponse) ToProto() (*v1.ExecutionPayload, error) { + return r.Data.ToProto() +} + +func (p *ExecutionPayload) ToProto() (*v1.ExecutionPayload, error) { + // TODO: it looks like BaseFeePerGas should probably be a uint + baseFeeHack := []byte(strconv.FormatUint(uint64(p.BaseFeePerGas), 10)) + txs := make([][]byte, len(p.Transactions)) + for i := range p.Transactions { + txs[i] = p.Transactions[i] + } + return &v1.ExecutionPayload{ + ParentHash: p.ParentHash, + FeeRecipient: p.FeeRecipient, + StateRoot: p.StateRoot, + ReceiptsRoot: p.ReceiptsRoot, + LogsBloom: p.LogsBloom, + PrevRandao: p.PrevRandao, + BlockNumber: uint64(p.BlockNumber), + GasLimit: uint64(p.GasLimit), + GasUsed: uint64(p.GasUsed), + Timestamp: uint64(p.Timestamp), + ExtraData: p.ExtraData, + BaseFeePerGas: baseFeeHack, + BlockHash: p.BlockHash, + Transactions: txs, + }, nil +} + +type SignedBlindedBeaconBlockBellatrix struct { + *eth.SignedBlindedBeaconBlockBellatrix +} + +type BlindedBeaconBlockBellatrix struct { + *eth.BlindedBeaconBlockBellatrix +} + +type BlindedBeaconBlockBodyBellatrix struct { + *eth.BlindedBeaconBlockBodyBellatrix +} + +func (r *SignedBlindedBeaconBlockBellatrix) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Message *BlindedBeaconBlockBellatrix `json:"message,omitempty"` + Signature hexSlice `json:"signature,omitempty"` + }{ + Message: &BlindedBeaconBlockBellatrix{r.SignedBlindedBeaconBlockBellatrix.Block}, + Signature: r.SignedBlindedBeaconBlockBellatrix.Signature, + }) +} + +func (b *BlindedBeaconBlockBellatrix) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Slot string `json:"slot"` + ProposerIndex string `json:"proposer_index,omitempty"` + ParentRoot hexSlice `json:"parent_root,omitempty"` + StateRoot hexSlice `json:"state_root,omitempty"` + Body *BlindedBeaconBlockBodyBellatrix `json:"body,omitempty"` + }{ + Slot: fmt.Sprintf("%d", b.Slot), + ProposerIndex: fmt.Sprintf("%d", b.ProposerIndex), + ParentRoot: b.ParentRoot, + StateRoot: b.StateRoot, + Body: &BlindedBeaconBlockBodyBellatrix{b.BlindedBeaconBlockBellatrix.Body}, + }) +} + +type ProposerSlashing struct { + *eth.ProposerSlashing +} + +func (s *ProposerSlashing) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + SignedHeader1 *SignedBeaconBlockHeader `json:"signed_header_1,omitempty"` + SignedHeader2 *SignedBeaconBlockHeader `json:"signed_header_2,omitempty"` + }{ + SignedHeader1: &SignedBeaconBlockHeader{s.ProposerSlashing.Header_1}, + SignedHeader2: &SignedBeaconBlockHeader{s.ProposerSlashing.Header_2}, + }) +} + +type SignedBeaconBlockHeader struct { + *eth.SignedBeaconBlockHeader +} + +func (h *SignedBeaconBlockHeader) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Header *BeaconBlockHeader `json:"message,omitempty"` + Signature hexSlice `json:"signature,omitempty"` + }{ + Header: &BeaconBlockHeader{h.SignedBeaconBlockHeader.Header}, + Signature: h.SignedBeaconBlockHeader.Signature, + }) +} + +type BeaconBlockHeader struct { + *eth.BeaconBlockHeader +} + +func (h *BeaconBlockHeader) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Slot string `json:"slot,omitempty"` + ProposerIndex string `json:"proposer_index,omitempty"` + ParentRoot hexSlice `json:"parent_root,omitempty"` + StateRoot hexSlice `json:"state_root,omitempty"` + BodyRoot hexSlice `json:"body_root,omitempty"` + }{ + Slot: fmt.Sprintf("%d", h.BeaconBlockHeader.Slot), + ProposerIndex: fmt.Sprintf("%d", h.BeaconBlockHeader.ProposerIndex), + ParentRoot: h.BeaconBlockHeader.ParentRoot, + StateRoot: h.BeaconBlockHeader.StateRoot, + BodyRoot: h.BeaconBlockHeader.BodyRoot, + }) +} + +type IndexedAttestation struct { + *eth.IndexedAttestation +} + +func (a *IndexedAttestation) MarshalJSON() ([]byte, error) { + indices := make([]string, len(a.IndexedAttestation.AttestingIndices)) + for i := range a.IndexedAttestation.AttestingIndices { + indices[i] = fmt.Sprintf("%d", a.AttestingIndices[i]) + } + return json.Marshal(struct { + AttestingIndices []string `json:"attesting_indices,omitempty"` + Data *AttestationData + Signature hexSlice `json:"signature,omitempty"` + }{ + AttestingIndices: indices, + Data: &AttestationData{a.IndexedAttestation.Data}, + Signature: a.IndexedAttestation.Signature, + }) +} + +type AttesterSlashing struct { + *eth.AttesterSlashing +} + +func (s *AttesterSlashing) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Attestation1 *IndexedAttestation `json:"attestation_1,omitempty"` + Attestation2 *IndexedAttestation `json:"attestation_2,omitempty"` + }{ + Attestation1: &IndexedAttestation{s.Attestation_1}, + Attestation2: &IndexedAttestation{s.Attestation_2}, + }) +} + +type Checkpoint struct { + *eth.Checkpoint +} + +func (c *Checkpoint) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Epoch string `json:"epoch,omitempty"` + Root hexSlice `json:"root,omitempty"` + }{ + Epoch: fmt.Sprintf("%d", c.Checkpoint.Epoch), + Root: c.Checkpoint.Root, + }) +} + +type AttestationData struct { + *eth.AttestationData +} + +func (a *AttestationData) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Slot string `json:"slot,omitempty"` + Index string `json:"index,omitempty"` + BeaconBlockRoot hexSlice `json:"beacon_block_root,omitempty"` + Source *Checkpoint `json:"source,omitempty"` + Target *Checkpoint `json:"target,omitempty"` + }{ + Slot: fmt.Sprintf("%d", a.AttestationData.Slot), + Index: fmt.Sprintf("%d", a.AttestationData.CommitteeIndex), + BeaconBlockRoot: a.AttestationData.BeaconBlockRoot, + Source: &Checkpoint{a.AttestationData.Source}, + Target: &Checkpoint{a.AttestationData.Target}, + }) +} + +type Attestation struct { + *eth.Attestation +} + +func (a *Attestation) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + AggregationBits hexSlice `json:"aggregation_bits,omitempty"` + Data *AttestationData `json:"data,omitempty"` + Signature hexSlice `json:"signature,omitempty" ssz-size:"96"` + }{ + AggregationBits: hexSlice(a.Attestation.AggregationBits), + Data: &AttestationData{a.Attestation.Data}, + Signature: a.Attestation.Signature, + }) +} + +type DepositData struct { + *eth.Deposit_Data +} + +func (d *DepositData) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + PublicKey hexSlice `json:"pubkey,omitempty"` + WithdrawalCredentials hexSlice `json:"withdrawal_credentials,omitempty"` + Amount string `json:"amount,omitempty"` + Signature hexSlice `json:"signature,omitempty"` + }{ + PublicKey: d.PublicKey, + WithdrawalCredentials: d.WithdrawalCredentials, + Amount: fmt.Sprintf("%d", d.Amount), + Signature: d.Signature, + }) +} + +type Deposit struct { + *eth.Deposit +} + +func (d *Deposit) MarshalJSON() ([]byte, error) { + proof := make([]hexSlice, len(d.Proof)) + for i := range d.Proof { + proof[i] = d.Proof[i] + } + return json.Marshal(struct { + Proof []hexSlice `json:"proof"` + Data *DepositData `json:"data"` + }{ + Proof: proof, + Data: &DepositData{Deposit_Data: d.Deposit.Data}, + }) +} + +type SignedVoluntaryExit struct { + *eth.SignedVoluntaryExit +} + +func (sve *SignedVoluntaryExit) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Message *VoluntaryExit `json:"message,omitempty"` + Signature hexSlice `json:"signature,omitempty"` + }{ + Signature: sve.SignedVoluntaryExit.Signature, + Message: &VoluntaryExit{sve.SignedVoluntaryExit.Exit}, + }) +} + +type VoluntaryExit struct { + *eth.VoluntaryExit +} + +func (ve *VoluntaryExit) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Epoch string `json:"epoch,omitempty"` + ValidatorIndex string `json:"validator_index,omitempty"` + }{ + Epoch: fmt.Sprintf("%d", ve.Epoch), + ValidatorIndex: fmt.Sprintf("%d", ve.ValidatorIndex), + }) +} + +type SyncAggregate struct { + *eth.SyncAggregate +} + +func (s *SyncAggregate) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + SyncCommitteeBits hexSlice `json:"sync_committee_bits,omitempty"` + SyncCommitteeSignature hexSlice `json:"sync_committee_signature,omitempty"` + }{ + SyncCommitteeBits: hexSlice(s.SyncAggregate.SyncCommitteeBits), + SyncCommitteeSignature: s.SyncAggregate.SyncCommitteeSignature, + }) +} + +type Eth1Data struct { + *eth.Eth1Data +} + +func (e *Eth1Data) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + DepositRoot hexSlice `json:"deposit_root,omitempty"` + DepositCount string `json:"deposit_count,omitempty"` + BlockHash hexSlice `json:"block_hash,omitempty"` + }{ + DepositRoot: e.DepositRoot, + DepositCount: fmt.Sprintf("%d", e.DepositCount), + BlockHash: e.BlockHash, + }) +} + +func (b *BlindedBeaconBlockBodyBellatrix) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + RandaoReveal hexSlice `json:"randao_reveal,omitempty"` + Eth1Data *Eth1Data `json:"eth1_data,omitempty"` + Graffiti hexSlice `json:"graffiti,omitempty"` + ProposerSlashings []*ProposerSlashing `json:"proposer_slashings,omitempty"` + AttesterSlashings []*AttesterSlashing `json:"attester_slashings,omitempty"` + Attestations []*Attestation `json:"attestations,omitempty"` + Deposits []*Deposit `json:"deposits,omitempty"` + VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits,omitempty"` + SyncAggregates *SyncAggregate `json:"sync_aggregate,omitempty"` + ExecutionPayloadHeader *ExecutionPayloadHeader `json:"execution_payload_header,omitempty"` + }{ + RandaoReveal: b.RandaoReveal, + Eth1Data: &Eth1Data{b.BlindedBeaconBlockBodyBellatrix.Eth1Data}, + Graffiti: b.BlindedBeaconBlockBodyBellatrix.Graffiti, + ProposerSlashings: []*ProposerSlashing{}, + AttesterSlashings: []*AttesterSlashing{}, + Attestations: []*Attestation{}, + Deposits: []*Deposit{}, + VoluntaryExits: []*SignedVoluntaryExit{}, + ExecutionPayloadHeader: &ExecutionPayloadHeader{ExecutionPayloadHeader: b.BlindedBeaconBlockBodyBellatrix.ExecutionPayloadHeader}, + }) +} diff --git a/api/client/builder/types_test.go b/api/client/builder/types_test.go new file mode 100644 index 000000000000..034f4f31a000 --- /dev/null +++ b/api/client/builder/types_test.go @@ -0,0 +1,621 @@ +package builder + +import ( + "encoding/json" + "fmt" + "math/big" + "strconv" + "testing" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/prysmaticlabs/go-bitfield" + v1 "github.com/prysmaticlabs/prysm/proto/engine/v1" + eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" + "github.com/prysmaticlabs/prysm/testing/require" +) + +func ezDecode(t *testing.T, s string) []byte { + v, err := hexutil.Decode(s) + require.NoError(t, err) + return v +} + +func TestSignedValidatorRegistration_MarshalJSON(t *testing.T) { + svr := ð.SignedValidatorRegistrationV1{ + Message: ð.ValidatorRegistrationV1{ + FeeRecipient: make([]byte, 20), + GasLimit: 0, + Timestamp: 0, + Pubkey: make([]byte, 48), + }, + Signature: make([]byte, 96), + } + je, err := json.Marshal(&SignedValidatorRegistration{SignedValidatorRegistrationV1: svr}) + require.NoError(t, err) + // decode with a struct w/ plain strings so we can check the string encoding of the hex fields + un := struct { + Message struct { + FeeRecipient string `json:"fee_recipient"` + Pubkey string `json:"pubkey"` + } `json:"message"` + Signature string `json:"signature"` + }{} + require.NoError(t, json.Unmarshal(je, &un)) + require.Equal(t, "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", un.Signature) + require.Equal(t, "0x0000000000000000000000000000000000000000", un.Message.FeeRecipient) + require.Equal(t, "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", un.Message.Pubkey) +} + +var testExampleHeaderResponse = `{ + "version": "bellatrix", + "data": { + "message": { + "header": { + "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", + "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "transactions_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" + }, + "value": "1", + "pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a" + }, + "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" + } +}` + +func TestExecutionHeaderResponseUnmarshal(t *testing.T) { + hr := &ExecHeaderResponse{} + require.NoError(t, json.Unmarshal([]byte(testExampleHeaderResponse), hr)) + cases := []struct { + expected string + actual string + name string + }{ + { + expected: "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", + actual: fmt.Sprintf("%#x", hr.Data.Signature), + name: "Signature", + }, + { + expected: "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a", + actual: fmt.Sprintf("%#x", hr.Data.Message.Pubkey), + name: "ExecHeaderResponse.Pubkey", + }, + { + expected: "1", + actual: hr.Data.Message.Value.String(), + name: "ExecHeaderResponse.Value", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: fmt.Sprintf("%#x", hr.Data.Message.Header.ParentHash), + name: "ExecHeaderResponse.ExecutionPayloadHeader.ParentHash", + }, + { + expected: "0xabcf8e0d4e9587369b2301d0790347320302cc09", + actual: fmt.Sprintf("%#x", hr.Data.Message.Header.FeeRecipient), + name: "ExecHeaderResponse.ExecutionPayloadHeader.FeeRecipient", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: fmt.Sprintf("%#x", hr.Data.Message.Header.StateRoot), + name: "ExecHeaderResponse.ExecutionPayloadHeader.StateRoot", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: fmt.Sprintf("%#x", hr.Data.Message.Header.ReceiptsRoot), + name: "ExecHeaderResponse.ExecutionPayloadHeader.ReceiptsRoot", + }, + { + expected: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + actual: fmt.Sprintf("%#x", hr.Data.Message.Header.LogsBloom), + name: "ExecHeaderResponse.ExecutionPayloadHeader.LogsBloom", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: fmt.Sprintf("%#x", hr.Data.Message.Header.PrevRandao), + name: "ExecHeaderResponse.ExecutionPayloadHeader.PrevRandao", + }, + { + expected: "1", + actual: fmt.Sprintf("%d", hr.Data.Message.Header.BlockNumber), + name: "ExecHeaderResponse.ExecutionPayloadHeader.BlockNumber", + }, + { + expected: "1", + actual: fmt.Sprintf("%d", hr.Data.Message.Header.GasLimit), + name: "ExecHeaderResponse.ExecutionPayloadHeader.GasLimit", + }, + { + expected: "1", + actual: fmt.Sprintf("%d", hr.Data.Message.Header.GasUsed), + name: "ExecHeaderResponse.ExecutionPayloadHeader.GasUsed", + }, + { + expected: "1", + actual: fmt.Sprintf("%d", hr.Data.Message.Header.Timestamp), + name: "ExecHeaderResponse.ExecutionPayloadHeader.Timestamp", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: fmt.Sprintf("%#x", hr.Data.Message.Header.ExtraData), + name: "ExecHeaderResponse.ExecutionPayloadHeader.ExtraData", + }, + { + expected: "1", + actual: fmt.Sprintf("%d", hr.Data.Message.Header.BaseFeePerGas), + name: "ExecHeaderResponse.ExecutionPayloadHeader.BaseFeePerGas", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: fmt.Sprintf("%#x", hr.Data.Message.Header.BlockHash), + name: "ExecHeaderResponse.ExecutionPayloadHeader.BlockHash", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: fmt.Sprintf("%#x", hr.Data.Message.Header.TransactionsRoot), + name: "ExecHeaderResponse.ExecutionPayloadHeader.TransactionsRoot", + }, + } + for _, c := range cases { + require.Equal(t, c.expected, c.actual, fmt.Sprintf("unexpected value for field %s", c.name)) + } +} + +func TestExecutionHeaderResponseToProto(t *testing.T) { + hr := &ExecHeaderResponse{} + require.NoError(t, json.Unmarshal([]byte(testExampleHeaderResponse), hr)) + p, err := hr.ToProto() + require.NoError(t, err) + signature, err := hexutil.Decode("0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505") + require.NoError(t, err) + pubkey, err := hexutil.Decode("0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a") + require.NoError(t, err) + parentHash, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + feeRecipient, err := hexutil.Decode("0xabcf8e0d4e9587369b2301d0790347320302cc09") + require.NoError(t, err) + stateRoot, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + receiptsRoot, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + logsBloom, err := hexutil.Decode("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") + require.NoError(t, err) + prevRandao, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + extraData, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + blockHash, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + txRoot, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + value := big.NewInt(0) + value, ok := value.SetString("1", 10) + require.Equal(t, true, ok) + expected := ð.SignedBuilderBid{ + Message: ð.BuilderBid{ + Header: ð.ExecutionPayloadHeader{ + ParentHash: parentHash, + FeeRecipient: feeRecipient, + StateRoot: stateRoot, + ReceiptsRoot: receiptsRoot, + LogsBloom: logsBloom, + PrevRandao: prevRandao, + BlockNumber: 1, + GasLimit: 1, + GasUsed: 1, + Timestamp: 1, + ExtraData: extraData, + // TODO assumes weird byte slice field + BaseFeePerGas: []byte(strconv.FormatUint(uint64(1), 10)), + BlockHash: blockHash, + TransactionsRoot: txRoot, + }, + // TODO assumes weird byte slice field + Value: value.Bytes(), + Pubkey: pubkey, + }, + Signature: signature, + } + require.DeepEqual(t, expected, p) +} + +var testExampleExecutionPayload = `{ + "version": "bellatrix", + "data": { + "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", + "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + "transactions": [ + "0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86" + ] + } +}` + +func TestExecutionPayloadResponseUnmarshal(t *testing.T) { + epr := &ExecPayloadResponse{} + require.NoError(t, json.Unmarshal([]byte(testExampleExecutionPayload), epr)) + cases := []struct { + expected string + actual string + name string + }{ + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: fmt.Sprintf("%#x", epr.Data.ParentHash), + name: "ExecPayloadResponse.ExecutionPayload.ParentHash", + }, + { + expected: "0xabcf8e0d4e9587369b2301d0790347320302cc09", + actual: fmt.Sprintf("%#x", epr.Data.FeeRecipient), + name: "ExecPayloadResponse.ExecutionPayload.FeeRecipient", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: fmt.Sprintf("%#x", epr.Data.StateRoot), + name: "ExecPayloadResponse.ExecutionPayload.StateRoot", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: fmt.Sprintf("%#x", epr.Data.ReceiptsRoot), + name: "ExecPayloadResponse.ExecutionPayload.ReceiptsRoot", + }, + { + expected: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + actual: fmt.Sprintf("%#x", epr.Data.LogsBloom), + name: "ExecPayloadResponse.ExecutionPayload.LogsBloom", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: fmt.Sprintf("%#x", epr.Data.PrevRandao), + name: "ExecPayloadResponse.ExecutionPayload.PrevRandao", + }, + { + expected: "1", + actual: fmt.Sprintf("%d", epr.Data.BlockNumber), + name: "ExecPayloadResponse.ExecutionPayload.BlockNumber", + }, + { + expected: "1", + actual: fmt.Sprintf("%d", epr.Data.GasLimit), + name: "ExecPayloadResponse.ExecutionPayload.GasLimit", + }, + { + expected: "1", + actual: fmt.Sprintf("%d", epr.Data.GasUsed), + name: "ExecPayloadResponse.ExecutionPayload.GasUsed", + }, + { + expected: "1", + actual: fmt.Sprintf("%d", epr.Data.Timestamp), + name: "ExecPayloadResponse.ExecutionPayload.Timestamp", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: fmt.Sprintf("%#x", epr.Data.ExtraData), + name: "ExecPayloadResponse.ExecutionPayload.ExtraData", + }, + { + expected: "1", + actual: fmt.Sprintf("%d", epr.Data.BaseFeePerGas), + name: "ExecPayloadResponse.ExecutionPayload.BaseFeePerGas", + }, + { + expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", + actual: fmt.Sprintf("%#x", epr.Data.BlockHash), + name: "ExecPayloadResponse.ExecutionPayload.BlockHash", + }, + } + for _, c := range cases { + require.Equal(t, c.expected, c.actual, fmt.Sprintf("unexpected value for field %s", c.name)) + } + require.Equal(t, 1, len(epr.Data.Transactions)) + txHash := "0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86" + require.Equal(t, txHash, fmt.Sprintf("%#x", epr.Data.Transactions[0])) +} + +func TestExecutionPayloadResponseToProto(t *testing.T) { + hr := &ExecPayloadResponse{} + require.NoError(t, json.Unmarshal([]byte(testExampleExecutionPayload), hr)) + p, err := hr.ToProto() + require.NoError(t, err) + + parentHash, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + feeRecipient, err := hexutil.Decode("0xabcf8e0d4e9587369b2301d0790347320302cc09") + require.NoError(t, err) + stateRoot, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + receiptsRoot, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + logsBloom, err := hexutil.Decode("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") + require.NoError(t, err) + prevRandao, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + extraData, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + blockHash, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") + require.NoError(t, err) + + tx, err := hexutil.Decode("0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86") + require.NoError(t, err) + txList := [][]byte{tx} + + expected := &v1.ExecutionPayload{ + ParentHash: parentHash, + FeeRecipient: feeRecipient, + StateRoot: stateRoot, + ReceiptsRoot: receiptsRoot, + LogsBloom: logsBloom, + PrevRandao: prevRandao, + BlockNumber: 1, + GasLimit: 1, + GasUsed: 1, + Timestamp: 1, + ExtraData: extraData, + // TODO assumes weird byte slice field + BaseFeePerGas: []byte(strconv.FormatUint(uint64(1), 10)), + BlockHash: blockHash, + Transactions: txList, + } + require.DeepEqual(t, expected, p) +} + +func TestEth1DataMarshal(t *testing.T) { + ed := &Eth1Data{ + Eth1Data: ð.Eth1Data{ + DepositRoot: make([]byte, 32), + DepositCount: 23, + BlockHash: make([]byte, 32), + }, + } + b, err := json.Marshal(ed) + require.NoError(t, err) + expected := `{"deposit_root":"0x0000000000000000000000000000000000000000000000000000000000000000","deposit_count":"23","block_hash":"0x0000000000000000000000000000000000000000000000000000000000000000"}` + require.Equal(t, expected, string(b)) +} + +func TestSyncAggregate_MarshalJSON(t *testing.T) { + sa := &SyncAggregate{ + ð.SyncAggregate{ + SyncCommitteeSignature: make([]byte, 48), + SyncCommitteeBits: bitfield.Bitvector512{0x01}, + }, + } + b, err := json.Marshal(sa) + require.NoError(t, err) + expected := `{"sync_committee_bits":"0x01","sync_committee_signature":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}` + require.Equal(t, expected, string(b)) +} + +func TestDeposit_MarshalJSON(t *testing.T) { + d := &Deposit{ + Deposit: ð.Deposit{ + Proof: [][]byte{ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2")}, + Data: ð.Deposit_Data{ + PublicKey: ezDecode(t, "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a"), + WithdrawalCredentials: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Amount: 1, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + }, + } + b, err := json.Marshal(d) + require.NoError(t, err) + expected := `{"proof":["0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"],"data":{"pubkey":"0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a","withdrawal_credentials":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","amount":"1","signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}}` + require.Equal(t, expected, string(b)) +} + +func TestVoluntaryExit(t *testing.T) { + ve := &SignedVoluntaryExit{ + SignedVoluntaryExit: ð.SignedVoluntaryExit{ + Exit: ð.VoluntaryExit{ + Epoch: 1, + ValidatorIndex: 1, + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + } + b, err := json.Marshal(ve) + require.NoError(t, err) + expected := `{"message":{"epoch":"1","validator_index":"1"},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}` + require.Equal(t, expected, string(b)) +} + +func TestAttestationMarshal(t *testing.T) { + a := &Attestation{ + Attestation: ð.Attestation{ + AggregationBits: bitfield.Bitlist{0x01}, + Data: ð.AttestationData{ + Slot: 1, + CommitteeIndex: 1, + BeaconBlockRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Source: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Target: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + } + b, err := json.Marshal(a) + require.NoError(t, err) + expected := `{"aggregation_bits":"0x01","data":{"slot":"1","index":"1","beacon_block_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","source":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"target":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}` + require.Equal(t, expected, string(b)) +} + +func TestAttesterSlashing_MarshalJSON(t *testing.T) { + as := &AttesterSlashing{ + AttesterSlashing: ð.AttesterSlashing{ + Attestation_1: ð.IndexedAttestation{ + AttestingIndices: []uint64{1}, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + Data: ð.AttestationData{ + Slot: 1, + CommitteeIndex: 1, + BeaconBlockRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Source: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Target: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + }, + }, + Attestation_2: ð.IndexedAttestation{ + AttestingIndices: []uint64{1}, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + Data: ð.AttestationData{ + Slot: 1, + CommitteeIndex: 1, + BeaconBlockRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Source: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Target: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + }, + }, + }, + } + b, err := json.Marshal(as) + require.NoError(t, err) + expected := `{"attestation_1":{"attesting_indices":["1"],"Data":{"slot":"1","index":"1","beacon_block_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","source":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"target":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"},"attestation_2":{"attesting_indices":["1"],"Data":{"slot":"1","index":"1","beacon_block_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","source":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"target":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}}` + require.Equal(t, expected, string(b)) +} + +func TestProposerSlashings(t *testing.T) { + ps := &ProposerSlashing{ð.ProposerSlashing{ + Header_1: ð.SignedBeaconBlockHeader{ + Header: ð.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BodyRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + Header_2: ð.SignedBeaconBlockHeader{ + Header: ð.BeaconBlockHeader{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BodyRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + }} + b, err := json.Marshal(ps) + require.NoError(t, err) + expected := `{"signed_header_1":{"message":{"slot":"1","proposer_index":"1","parent_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","state_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","body_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"},"signed_header_2":{"message":{"slot":"1","proposer_index":"1","parent_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","state_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","body_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}}` + require.Equal(t, expected, string(b)) +} + +func TestExecutionPayloadHeader_MarshalJSON(t *testing.T) { + bfpg := []byte(strconv.FormatUint(1, 10)) + h := &ExecutionPayloadHeader{ + ExecutionPayloadHeader: ð.ExecutionPayloadHeader{ + ParentHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + FeeRecipient: ezDecode(t, "0xabcf8e0d4e9587369b2301d0790347320302cc09"), + StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + ReceiptsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + LogsBloom: ezDecode(t, "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + PrevRandao: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BlockNumber: 1, + GasLimit: 1, + GasUsed: 1, + Timestamp: 1, + ExtraData: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BaseFeePerGas: bfpg, + BlockHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + TransactionsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + } + b, err := json.Marshal(h) + require.NoError(t, err) + expected := `{"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","block_hash":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","transactions_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}` + require.Equal(t, expected, string(b)) +} + +var testBuilderBid = `{ + "version":"bellatrix", + "data":{ + "message":{ + "header":{ + "parent_hash":"0xa0513a503d5bd6e89a144c3268e5b7e9da9dbf63df125a360e3950a7d0d67131", + "fee_recipient":"0xdfb434922631787e43725c6b926e989875125751", + "state_root":"0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45", + "receipts_root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logs_bloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prev_randao":"0xc2fa210081542a87f334b7b14a2da3275e4b281dd77b007bcfcb10e34c42052e", + "block_number":"1", + "gas_limit":"10000000", + "gas_used":"0", + "timestamp":"4660", + "extra_data":"0x", + "base_fee_per_gas":"7", + "block_hash":"0x10746fa06c248e7eacd4ff8ad8b48a826c227387ee31a6aa5eb4d83ddad34f07", + "transactions_root":"0x7ffe241ea60187fdb0187bfa22de35d1f9bed7ab061d9401fd47e34a54fbede1" + }, + "value":"452312848583266388373324160190187140051835877600158453279131187530910662656", + "pubkey":"0x8645866c95cbc2e08bc77ccad473540eddf4a1f51a2a8edc8d7a673824218f7f68fe565f1ab38dadd5c855b45bbcec95" + }, + "signature":"0x9183ebc1edf9c3ab2bbd7abdc3b59c6b249d6647b5289a97eea36d9d61c47f12e283f64d928b1e7f5b8a5182b714fa921954678ea28ca574f5f232b2f78cf8900915a2993b396e3471e0655291fec143a300d41408f66478c8208e0f9be851dc" + } +}` + +func TestBuilderBidUnmarshalUint256(t *testing.T) { + base10 := "452312848583266388373324160190187140051835877600158453279131187530910662656" + var expectedValue big.Int + require.NoError(t, expectedValue.UnmarshalText([]byte(base10))) + r := &ExecHeaderResponse{} + require.NoError(t, json.Unmarshal([]byte(testBuilderBid), r)) + //require.Equal(t, expectedValue, r.Data.Message.Value) + marshaled := r.Data.Message.Value.String() + require.Equal(t, base10, marshaled) + require.Equal(t, 0, expectedValue.Cmp(r.Data.Message.Value.Int)) +} + +func TestMathBigUnmarshal(t *testing.T) { + base10 := "452312848583266388373324160190187140051835877600158453279131187530910662656" + var expectedValue big.Int + require.NoError(t, expectedValue.UnmarshalText([]byte(base10))) + marshaled, err := expectedValue.MarshalText() + require.NoError(t, err) + require.Equal(t, base10, string(marshaled)) + + var u256 Uint256 + require.NoError(t, u256.UnmarshalText([]byte("452312848583266388373324160190187140051835877600158453279131187530910662656"))) + t.Logf("%v", u256.Bytes()) +} diff --git a/proto/prysm/v1alpha1/beacon_block.pb.go b/proto/prysm/v1alpha1/beacon_block.pb.go index 74ad5d7613f2..492d3a58a3f8 100755 --- a/proto/prysm/v1alpha1/beacon_block.pb.go +++ b/proto/prysm/v1alpha1/beacon_block.pb.go @@ -1970,6 +1970,250 @@ func (x *ExecutionPayloadHeader) GetTransactionsRoot() []byte { return nil } +type ValidatorRegistrationV1 struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FeeRecipient []byte `protobuf:"bytes,1,opt,name=fee_recipient,json=feeRecipient,proto3" json:"fee_recipient,omitempty" ssz-size:"20"` + GasLimit uint64 `protobuf:"varint,2,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty"` + Timestamp uint64 `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + Pubkey []byte `protobuf:"bytes,4,opt,name=pubkey,proto3" json:"pubkey,omitempty" ssz-size:"48"` +} + +func (x *ValidatorRegistrationV1) Reset() { + *x = ValidatorRegistrationV1{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ValidatorRegistrationV1) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ValidatorRegistrationV1) ProtoMessage() {} + +func (x *ValidatorRegistrationV1) ProtoReflect() protoreflect.Message { + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ValidatorRegistrationV1.ProtoReflect.Descriptor instead. +func (*ValidatorRegistrationV1) Descriptor() ([]byte, []int) { + return file_proto_prysm_v1alpha1_beacon_block_proto_rawDescGZIP(), []int{25} +} + +func (x *ValidatorRegistrationV1) GetFeeRecipient() []byte { + if x != nil { + return x.FeeRecipient + } + return nil +} + +func (x *ValidatorRegistrationV1) GetGasLimit() uint64 { + if x != nil { + return x.GasLimit + } + return 0 +} + +func (x *ValidatorRegistrationV1) GetTimestamp() uint64 { + if x != nil { + return x.Timestamp + } + return 0 +} + +func (x *ValidatorRegistrationV1) GetPubkey() []byte { + if x != nil { + return x.Pubkey + } + return nil +} + +type SignedValidatorRegistrationV1 struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message *ValidatorRegistrationV1 `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty" ssz-size:"96"` +} + +func (x *SignedValidatorRegistrationV1) Reset() { + *x = SignedValidatorRegistrationV1{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignedValidatorRegistrationV1) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignedValidatorRegistrationV1) ProtoMessage() {} + +func (x *SignedValidatorRegistrationV1) ProtoReflect() protoreflect.Message { + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignedValidatorRegistrationV1.ProtoReflect.Descriptor instead. +func (*SignedValidatorRegistrationV1) Descriptor() ([]byte, []int) { + return file_proto_prysm_v1alpha1_beacon_block_proto_rawDescGZIP(), []int{26} +} + +func (x *SignedValidatorRegistrationV1) GetMessage() *ValidatorRegistrationV1 { + if x != nil { + return x.Message + } + return nil +} + +func (x *SignedValidatorRegistrationV1) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + +type BuilderBid struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Header *ExecutionPayloadHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty" ssz-size:"32"` + Pubkey []byte `protobuf:"bytes,3,opt,name=pubkey,proto3" json:"pubkey,omitempty" ssz-size:"48"` +} + +func (x *BuilderBid) Reset() { + *x = BuilderBid{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BuilderBid) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BuilderBid) ProtoMessage() {} + +func (x *BuilderBid) ProtoReflect() protoreflect.Message { + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BuilderBid.ProtoReflect.Descriptor instead. +func (*BuilderBid) Descriptor() ([]byte, []int) { + return file_proto_prysm_v1alpha1_beacon_block_proto_rawDescGZIP(), []int{27} +} + +func (x *BuilderBid) GetHeader() *ExecutionPayloadHeader { + if x != nil { + return x.Header + } + return nil +} + +func (x *BuilderBid) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +func (x *BuilderBid) GetPubkey() []byte { + if x != nil { + return x.Pubkey + } + return nil +} + +type SignedBuilderBid struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message *BuilderBid `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty" ssz-size:"96"` +} + +func (x *SignedBuilderBid) Reset() { + *x = SignedBuilderBid{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignedBuilderBid) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignedBuilderBid) ProtoMessage() {} + +func (x *SignedBuilderBid) ProtoReflect() protoreflect.Message { + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignedBuilderBid.ProtoReflect.Descriptor instead. +func (*SignedBuilderBid) Descriptor() ([]byte, []int) { + return file_proto_prysm_v1alpha1_beacon_block_proto_rawDescGZIP(), []int{28} +} + +func (x *SignedBuilderBid) GetMessage() *BuilderBid { + if x != nil { + return x.Message + } + return nil +} + +func (x *SignedBuilderBid) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + type Deposit_Data struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1984,7 +2228,7 @@ type Deposit_Data struct { func (x *Deposit_Data) Reset() { *x = Deposit_Data{} if protoimpl.UnsafeEnabled { - mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[25] + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[29] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1997,7 +2241,7 @@ func (x *Deposit_Data) String() string { func (*Deposit_Data) ProtoMessage() {} func (x *Deposit_Data) ProtoReflect() protoreflect.Message { - mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[25] + mi := &file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[29] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2562,17 +2806,53 @@ var file_proto_prysm_v1alpha1_beacon_block_proto_rawDesc = []byte{ 0x0a, 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x6f, 0x6f, 0x74, 0x42, 0x98, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, 0x65, - 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x31, 0x42, 0x10, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, 0x2f, - 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, 0x73, - 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa, 0x02, - 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, - 0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6f, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x17, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, + 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x12, + 0x2b, 0x0a, 0x0d, 0x66, 0x65, 0x65, 0x5f, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x32, 0x30, 0x52, 0x0c, + 0x66, 0x65, 0x65, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, + 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1e, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, + 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, + 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x22, 0x8f, 0x01, 0x0a, 0x1d, 0x53, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x12, 0x48, 0x0a, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x65, 0x74, 0x68, + 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x2e, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x31, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09, + 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x91, 0x01, 0x0a, 0x0a, 0x42, 0x75, + 0x69, 0x6c, 0x64, 0x65, 0x72, 0x42, 0x69, 0x64, 0x12, 0x45, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, + 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, + 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, + 0x1c, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, + 0x8a, 0xb5, 0x18, 0x02, 0x33, 0x32, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1e, 0x0a, + 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x06, 0x8a, + 0xb5, 0x18, 0x02, 0x34, 0x38, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x22, 0x75, 0x0a, + 0x10, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x65, 0x72, 0x42, 0x69, + 0x64, 0x12, 0x3b, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, + 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, + 0x65, 0x72, 0x42, 0x69, 0x64, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, + 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x42, 0x06, 0x8a, 0xb5, 0x18, 0x02, 0x39, 0x36, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x42, 0x98, 0x01, 0x0a, 0x19, 0x6f, 0x72, 0x67, 0x2e, 0x65, 0x74, 0x68, + 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x65, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0x42, 0x10, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x6c, 0x61, 0x62, 0x73, + 0x2f, 0x70, 0x72, 0x79, 0x73, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x79, + 0x73, 0x6d, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x65, 0x74, 0x68, 0xaa, + 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x45, 0x74, 0x68, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x15, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x75, 0x6d, 0x5c, 0x45, 0x74, 0x68, 0x5c, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2587,7 +2867,7 @@ func file_proto_prysm_v1alpha1_beacon_block_proto_rawDescGZIP() []byte { return file_proto_prysm_v1alpha1_beacon_block_proto_rawDescData } -var file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes = make([]protoimpl.MessageInfo, 26) +var file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes = make([]protoimpl.MessageInfo, 30) var file_proto_prysm_v1alpha1_beacon_block_proto_goTypes = []interface{}{ (*GenericSignedBeaconBlock)(nil), // 0: ethereum.eth.v1alpha1.GenericSignedBeaconBlock (*GenericBeaconBlock)(nil), // 1: ethereum.eth.v1alpha1.GenericBeaconBlock @@ -2614,10 +2894,14 @@ var file_proto_prysm_v1alpha1_beacon_block_proto_goTypes = []interface{}{ (*BlindedBeaconBlockBellatrix)(nil), // 22: ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix (*BlindedBeaconBlockBodyBellatrix)(nil), // 23: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix (*ExecutionPayloadHeader)(nil), // 24: ethereum.eth.v1alpha1.ExecutionPayloadHeader - (*Deposit_Data)(nil), // 25: ethereum.eth.v1alpha1.Deposit.Data - (*Attestation)(nil), // 26: ethereum.eth.v1alpha1.Attestation - (*AttestationData)(nil), // 27: ethereum.eth.v1alpha1.AttestationData - (*v1.ExecutionPayload)(nil), // 28: ethereum.engine.v1.ExecutionPayload + (*ValidatorRegistrationV1)(nil), // 25: ethereum.eth.v1alpha1.ValidatorRegistrationV1 + (*SignedValidatorRegistrationV1)(nil), // 26: ethereum.eth.v1alpha1.SignedValidatorRegistrationV1 + (*BuilderBid)(nil), // 27: ethereum.eth.v1alpha1.BuilderBid + (*SignedBuilderBid)(nil), // 28: ethereum.eth.v1alpha1.SignedBuilderBid + (*Deposit_Data)(nil), // 29: ethereum.eth.v1alpha1.Deposit.Data + (*Attestation)(nil), // 30: ethereum.eth.v1alpha1.Attestation + (*AttestationData)(nil), // 31: ethereum.eth.v1alpha1.AttestationData + (*v1.ExecutionPayload)(nil), // 32: ethereum.engine.v1.ExecutionPayload } var file_proto_prysm_v1alpha1_beacon_block_proto_depIdxs = []int32{ 3, // 0: ethereum.eth.v1alpha1.GenericSignedBeaconBlock.phase0:type_name -> ethereum.eth.v1alpha1.SignedBeaconBlock @@ -2635,13 +2919,13 @@ var file_proto_prysm_v1alpha1_beacon_block_proto_depIdxs = []int32{ 13, // 12: ethereum.eth.v1alpha1.BeaconBlockBody.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data 8, // 13: ethereum.eth.v1alpha1.BeaconBlockBody.proposer_slashings:type_name -> ethereum.eth.v1alpha1.ProposerSlashing 9, // 14: ethereum.eth.v1alpha1.BeaconBlockBody.attester_slashings:type_name -> ethereum.eth.v1alpha1.AttesterSlashing - 26, // 15: ethereum.eth.v1alpha1.BeaconBlockBody.attestations:type_name -> ethereum.eth.v1alpha1.Attestation + 30, // 15: ethereum.eth.v1alpha1.BeaconBlockBody.attestations:type_name -> ethereum.eth.v1alpha1.Attestation 10, // 16: ethereum.eth.v1alpha1.BeaconBlockBody.deposits:type_name -> ethereum.eth.v1alpha1.Deposit 12, // 17: ethereum.eth.v1alpha1.BeaconBlockBody.voluntary_exits:type_name -> ethereum.eth.v1alpha1.SignedVoluntaryExit 13, // 18: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data 8, // 19: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.proposer_slashings:type_name -> ethereum.eth.v1alpha1.ProposerSlashing 9, // 20: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.attester_slashings:type_name -> ethereum.eth.v1alpha1.AttesterSlashing - 26, // 21: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.attestations:type_name -> ethereum.eth.v1alpha1.Attestation + 30, // 21: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.attestations:type_name -> ethereum.eth.v1alpha1.Attestation 10, // 22: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.deposits:type_name -> ethereum.eth.v1alpha1.Deposit 12, // 23: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.voluntary_exits:type_name -> ethereum.eth.v1alpha1.SignedVoluntaryExit 17, // 24: ethereum.eth.v1alpha1.BeaconBlockBodyAltair.sync_aggregate:type_name -> ethereum.eth.v1alpha1.SyncAggregate @@ -2649,35 +2933,38 @@ var file_proto_prysm_v1alpha1_beacon_block_proto_depIdxs = []int32{ 15, // 26: ethereum.eth.v1alpha1.ProposerSlashing.header_2:type_name -> ethereum.eth.v1alpha1.SignedBeaconBlockHeader 16, // 27: ethereum.eth.v1alpha1.AttesterSlashing.attestation_1:type_name -> ethereum.eth.v1alpha1.IndexedAttestation 16, // 28: ethereum.eth.v1alpha1.AttesterSlashing.attestation_2:type_name -> ethereum.eth.v1alpha1.IndexedAttestation - 25, // 29: ethereum.eth.v1alpha1.Deposit.data:type_name -> ethereum.eth.v1alpha1.Deposit.Data + 29, // 29: ethereum.eth.v1alpha1.Deposit.data:type_name -> ethereum.eth.v1alpha1.Deposit.Data 11, // 30: ethereum.eth.v1alpha1.SignedVoluntaryExit.exit:type_name -> ethereum.eth.v1alpha1.VoluntaryExit 14, // 31: ethereum.eth.v1alpha1.SignedBeaconBlockHeader.header:type_name -> ethereum.eth.v1alpha1.BeaconBlockHeader - 27, // 32: ethereum.eth.v1alpha1.IndexedAttestation.data:type_name -> ethereum.eth.v1alpha1.AttestationData + 31, // 32: ethereum.eth.v1alpha1.IndexedAttestation.data:type_name -> ethereum.eth.v1alpha1.AttestationData 19, // 33: ethereum.eth.v1alpha1.SignedBeaconBlockBellatrix.block:type_name -> ethereum.eth.v1alpha1.BeaconBlockBellatrix 20, // 34: ethereum.eth.v1alpha1.BeaconBlockBellatrix.body:type_name -> ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix 13, // 35: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data 8, // 36: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.proposer_slashings:type_name -> ethereum.eth.v1alpha1.ProposerSlashing 9, // 37: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.attester_slashings:type_name -> ethereum.eth.v1alpha1.AttesterSlashing - 26, // 38: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.attestations:type_name -> ethereum.eth.v1alpha1.Attestation + 30, // 38: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.attestations:type_name -> ethereum.eth.v1alpha1.Attestation 10, // 39: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.deposits:type_name -> ethereum.eth.v1alpha1.Deposit 12, // 40: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.voluntary_exits:type_name -> ethereum.eth.v1alpha1.SignedVoluntaryExit 17, // 41: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.sync_aggregate:type_name -> ethereum.eth.v1alpha1.SyncAggregate - 28, // 42: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.execution_payload:type_name -> ethereum.engine.v1.ExecutionPayload + 32, // 42: ethereum.eth.v1alpha1.BeaconBlockBodyBellatrix.execution_payload:type_name -> ethereum.engine.v1.ExecutionPayload 22, // 43: ethereum.eth.v1alpha1.SignedBlindedBeaconBlockBellatrix.block:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix 23, // 44: ethereum.eth.v1alpha1.BlindedBeaconBlockBellatrix.body:type_name -> ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix 13, // 45: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.eth1_data:type_name -> ethereum.eth.v1alpha1.Eth1Data 8, // 46: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.proposer_slashings:type_name -> ethereum.eth.v1alpha1.ProposerSlashing 9, // 47: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.attester_slashings:type_name -> ethereum.eth.v1alpha1.AttesterSlashing - 26, // 48: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.attestations:type_name -> ethereum.eth.v1alpha1.Attestation + 30, // 48: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.attestations:type_name -> ethereum.eth.v1alpha1.Attestation 10, // 49: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.deposits:type_name -> ethereum.eth.v1alpha1.Deposit 12, // 50: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.voluntary_exits:type_name -> ethereum.eth.v1alpha1.SignedVoluntaryExit 17, // 51: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.sync_aggregate:type_name -> ethereum.eth.v1alpha1.SyncAggregate 24, // 52: ethereum.eth.v1alpha1.BlindedBeaconBlockBodyBellatrix.execution_payload_header:type_name -> ethereum.eth.v1alpha1.ExecutionPayloadHeader - 53, // [53:53] is the sub-list for method output_type - 53, // [53:53] is the sub-list for method input_type - 53, // [53:53] is the sub-list for extension type_name - 53, // [53:53] is the sub-list for extension extendee - 0, // [0:53] is the sub-list for field type_name + 25, // 53: ethereum.eth.v1alpha1.SignedValidatorRegistrationV1.message:type_name -> ethereum.eth.v1alpha1.ValidatorRegistrationV1 + 24, // 54: ethereum.eth.v1alpha1.BuilderBid.header:type_name -> ethereum.eth.v1alpha1.ExecutionPayloadHeader + 27, // 55: ethereum.eth.v1alpha1.SignedBuilderBid.message:type_name -> ethereum.eth.v1alpha1.BuilderBid + 56, // [56:56] is the sub-list for method output_type + 56, // [56:56] is the sub-list for method input_type + 56, // [56:56] is the sub-list for extension type_name + 56, // [56:56] is the sub-list for extension extendee + 0, // [0:56] is the sub-list for field type_name } func init() { file_proto_prysm_v1alpha1_beacon_block_proto_init() } @@ -2988,6 +3275,54 @@ func file_proto_prysm_v1alpha1_beacon_block_proto_init() { } } file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ValidatorRegistrationV1); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignedValidatorRegistrationV1); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BuilderBid); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignedBuilderBid); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_prysm_v1alpha1_beacon_block_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Deposit_Data); i { case 0: return &v.state @@ -3018,7 +3353,7 @@ func file_proto_prysm_v1alpha1_beacon_block_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_prysm_v1alpha1_beacon_block_proto_rawDesc, NumEnums: 0, - NumMessages: 26, + NumMessages: 30, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/prysm/v1alpha1/beacon_block.proto b/proto/prysm/v1alpha1/beacon_block.proto index 3a6338abc69c..93152f296ffc 100644 --- a/proto/prysm/v1alpha1/beacon_block.proto +++ b/proto/prysm/v1alpha1/beacon_block.proto @@ -439,3 +439,26 @@ message ExecutionPayloadHeader { bytes block_hash = 13 [(ethereum.eth.ext.ssz_size) = "32"]; bytes transactions_root = 14 [(ethereum.eth.ext.ssz_size) = "32"]; } + +message ValidatorRegistrationV1 { + bytes fee_recipient = 1 [(ethereum.eth.ext.ssz_size) = "20"]; + uint64 gas_limit = 2; + uint64 timestamp = 3; + bytes pubkey = 4 [(ethereum.eth.ext.ssz_size) = "48"]; +} + +message SignedValidatorRegistrationV1 { + ValidatorRegistrationV1 message = 1 ; + bytes signature = 2 [(ethereum.eth.ext.ssz_size) = "96"]; +} + +message BuilderBid { + ExecutionPayloadHeader header = 1 ; + bytes value = 2 [(ethereum.eth.ext.ssz_size) = "32"]; + bytes pubkey = 3 [(ethereum.eth.ext.ssz_size) = "48"]; +} + +message SignedBuilderBid { + BuilderBid message = 1 ; + bytes signature = 2 [(ethereum.eth.ext.ssz_size) = "96"]; +} From d6e832d7a3487ab7129146def38bafebed9ffcb5 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Thu, 19 May 2022 18:51:19 -0500 Subject: [PATCH 02/21] unexport error --- api/client/builder/client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client/builder/client.go b/api/client/builder/client.go index 25ecccb4ecf0..fb2113dd3e77 100644 --- a/api/client/builder/client.go +++ b/api/client/builder/client.go @@ -27,7 +27,7 @@ const ( postRegisterValidatorPath = "/eth/v1/builder/validators" ) -var ErrMalformedHostname = errors.New("hostname must include port, separated by one colon, like example.com:3500") +var errMalformedHostname = errors.New("hostname must include port, separated by one colon, like example.com:3500") // ClientOpt is a functional option for the Client type (http.Client wrapper) type ClientOpt func(*Client) @@ -72,7 +72,7 @@ func urlForHost(h string) (*url.URL, error) { // try to parse as host:port host, port, err := net.SplitHostPort(h) if err != nil { - return nil, ErrMalformedHostname + return nil, errMalformedHostname } return &url.URL{Host: fmt.Sprintf("%s:%s", host, port), Scheme: "http"}, nil } From c89401f452014d7cfc841e1758ab93cbc9461f66 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 08:25:57 -0500 Subject: [PATCH 03/21] thanks, DeepSource! --- api/client/builder/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client/builder/client.go b/api/client/builder/client.go index fb2113dd3e77..61f697e2d2fc 100644 --- a/api/client/builder/client.go +++ b/api/client/builder/client.go @@ -74,7 +74,7 @@ func urlForHost(h string) (*url.URL, error) { if err != nil { return nil, errMalformedHostname } - return &url.URL{Host: fmt.Sprintf("%s:%s", host, port), Scheme: "http"}, nil + return &url.URL{Host: net.JoinHostPort(host, port), Scheme: "http"}, nil } // NodeURL returns a human-readable string representation of the beacon node base url. From 9d40adb669e27ec358b85d122159e4b184e0fec2 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 08:26:21 -0500 Subject: [PATCH 04/21] replace hexSlice w/ hexutil.Bytes --- api/client/builder/types.go | 113 ++++++++++++++----------------- api/client/builder/types_test.go | 40 +++++------ 2 files changed, 69 insertions(+), 84 deletions(-) diff --git a/api/client/builder/types.go b/api/client/builder/types.go index fe42f12cd1ac..c26675740a9f 100644 --- a/api/client/builder/types.go +++ b/api/client/builder/types.go @@ -23,7 +23,7 @@ type ValidatorRegistration struct { func (r *SignedValidatorRegistration) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Message *ValidatorRegistration `json:"message,omitempty"` - Signature hexSlice `json:"signature,omitempty"` + Signature hexutil.Bytes `json:"signature,omitempty"` }{ Message: &ValidatorRegistration{r.Message}, Signature: r.SignedValidatorRegistrationV1.Signature, @@ -32,10 +32,10 @@ func (r *SignedValidatorRegistration) MarshalJSON() ([]byte, error) { func (r *ValidatorRegistration) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - FeeRecipient hexSlice `json:"fee_recipient,omitempty"` + FeeRecipient hexutil.Bytes `json:"fee_recipient,omitempty"` GasLimit string `json:"gas_limit,omitempty"` Timestamp string `json:"timestamp,omitempty"` - Pubkey hexSlice `json:"pubkey,omitempty"` + Pubkey hexutil.Bytes `json:"pubkey,omitempty"` *eth.ValidatorRegistrationV1 }{ FeeRecipient: r.FeeRecipient, @@ -46,21 +46,6 @@ func (r *ValidatorRegistration) MarshalJSON() ([]byte, error) { }) } -type hexSlice []byte - -func (hs hexSlice) MarshalText() ([]byte, error) { - return []byte(fmt.Sprintf("%#x", hs)), nil -} - -func (hs *hexSlice) UnmarshalText(t []byte) error { - decoded, err := hexutil.Decode(string(t)) - if err != nil { - return errors.Wrapf(err, "error unmarshaling text value %s", string(t)) - } - *hs = decoded - return nil -} - type Uint256 struct { *big.Int } @@ -110,7 +95,7 @@ func (s Uint64String) MarshalText() ([]byte, error) { type ExecHeaderResponse struct { Version string `json:"version,omitempty"` Data struct { - Signature hexSlice `json:"signature,omitempty"` + Signature hexutil.Bytes `json:"signature,omitempty"` Message *BuilderBid `json:"message,omitempty"` } `json:"data,omitempty"` } @@ -162,24 +147,24 @@ func (h *ExecutionPayloadHeader) ToProto() (*eth.ExecutionPayloadHeader, error) type BuilderBid struct { Header *ExecutionPayloadHeader `json:"header,omitempty"` Value Uint256 `json:"value,omitempty"` - Pubkey hexSlice `json:"pubkey,omitempty"` + Pubkey hexutil.Bytes `json:"pubkey,omitempty"` } type ExecutionPayloadHeader struct { - ParentHash hexSlice `json:"parent_hash,omitempty"` - FeeRecipient hexSlice `json:"fee_recipient,omitempty"` - StateRoot hexSlice `json:"state_root,omitempty"` - ReceiptsRoot hexSlice `json:"receipts_root,omitempty"` - LogsBloom hexSlice `json:"logs_bloom,omitempty"` - PrevRandao hexSlice `json:"prev_randao,omitempty"` + ParentHash hexutil.Bytes `json:"parent_hash,omitempty"` + FeeRecipient hexutil.Bytes `json:"fee_recipient,omitempty"` + StateRoot hexutil.Bytes `json:"state_root,omitempty"` + ReceiptsRoot hexutil.Bytes `json:"receipts_root,omitempty"` + LogsBloom hexutil.Bytes `json:"logs_bloom,omitempty"` + PrevRandao hexutil.Bytes `json:"prev_randao,omitempty"` BlockNumber Uint64String `json:"block_number,omitempty"` GasLimit Uint64String `json:"gas_limit,omitempty"` GasUsed Uint64String `json:"gas_used,omitempty"` Timestamp Uint64String `json:"timestamp,omitempty"` - ExtraData hexSlice `json:"extra_data,omitempty"` + ExtraData hexutil.Bytes `json:"extra_data,omitempty"` BaseFeePerGas Uint64String `json:"base_fee_per_gas,omitempty"` - BlockHash hexSlice `json:"block_hash,omitempty"` - TransactionsRoot hexSlice `json:"transactions_root,omitempty"` + BlockHash hexutil.Bytes `json:"block_hash,omitempty"` + TransactionsRoot hexutil.Bytes `json:"transactions_root,omitempty"` *eth.ExecutionPayloadHeader } @@ -214,20 +199,20 @@ type ExecPayloadResponse struct { } type ExecutionPayload struct { - ParentHash hexSlice `json:"parent_hash,omitempty"` - FeeRecipient hexSlice `json:"fee_recipient,omitempty"` - StateRoot hexSlice `json:"state_root,omitempty"` - ReceiptsRoot hexSlice `json:"receipts_root,omitempty"` - LogsBloom hexSlice `json:"logs_bloom,omitempty"` - PrevRandao hexSlice `json:"prev_randao,omitempty"` + ParentHash hexutil.Bytes `json:"parent_hash,omitempty"` + FeeRecipient hexutil.Bytes `json:"fee_recipient,omitempty"` + StateRoot hexutil.Bytes `json:"state_root,omitempty"` + ReceiptsRoot hexutil.Bytes `json:"receipts_root,omitempty"` + LogsBloom hexutil.Bytes `json:"logs_bloom,omitempty"` + PrevRandao hexutil.Bytes `json:"prev_randao,omitempty"` BlockNumber Uint64String `json:"block_number,omitempty"` GasLimit Uint64String `json:"gas_limit,omitempty"` GasUsed Uint64String `json:"gas_used,omitempty"` Timestamp Uint64String `json:"timestamp,omitempty"` - ExtraData hexSlice `json:"extra_data,omitempty"` + ExtraData hexutil.Bytes `json:"extra_data,omitempty"` BaseFeePerGas Uint64String `json:"base_fee_per_gas,omitempty"` - BlockHash hexSlice `json:"block_hash,omitempty"` - Transactions []hexSlice `json:"transactions,omitempty"` + BlockHash hexutil.Bytes `json:"block_hash,omitempty"` + Transactions []hexutil.Bytes `json:"transactions,omitempty"` } func (r *ExecPayloadResponse) ToProto() (*v1.ExecutionPayload, error) { @@ -274,7 +259,7 @@ type BlindedBeaconBlockBodyBellatrix struct { func (r *SignedBlindedBeaconBlockBellatrix) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Message *BlindedBeaconBlockBellatrix `json:"message,omitempty"` - Signature hexSlice `json:"signature,omitempty"` + Signature hexutil.Bytes `json:"signature,omitempty"` }{ Message: &BlindedBeaconBlockBellatrix{r.SignedBlindedBeaconBlockBellatrix.Block}, Signature: r.SignedBlindedBeaconBlockBellatrix.Signature, @@ -285,8 +270,8 @@ func (b *BlindedBeaconBlockBellatrix) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Slot string `json:"slot"` ProposerIndex string `json:"proposer_index,omitempty"` - ParentRoot hexSlice `json:"parent_root,omitempty"` - StateRoot hexSlice `json:"state_root,omitempty"` + ParentRoot hexutil.Bytes `json:"parent_root,omitempty"` + StateRoot hexutil.Bytes `json:"state_root,omitempty"` Body *BlindedBeaconBlockBodyBellatrix `json:"body,omitempty"` }{ Slot: fmt.Sprintf("%d", b.Slot), @@ -318,7 +303,7 @@ type SignedBeaconBlockHeader struct { func (h *SignedBeaconBlockHeader) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Header *BeaconBlockHeader `json:"message,omitempty"` - Signature hexSlice `json:"signature,omitempty"` + Signature hexutil.Bytes `json:"signature,omitempty"` }{ Header: &BeaconBlockHeader{h.SignedBeaconBlockHeader.Header}, Signature: h.SignedBeaconBlockHeader.Signature, @@ -333,9 +318,9 @@ func (h *BeaconBlockHeader) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Slot string `json:"slot,omitempty"` ProposerIndex string `json:"proposer_index,omitempty"` - ParentRoot hexSlice `json:"parent_root,omitempty"` - StateRoot hexSlice `json:"state_root,omitempty"` - BodyRoot hexSlice `json:"body_root,omitempty"` + ParentRoot hexutil.Bytes `json:"parent_root,omitempty"` + StateRoot hexutil.Bytes `json:"state_root,omitempty"` + BodyRoot hexutil.Bytes `json:"body_root,omitempty"` }{ Slot: fmt.Sprintf("%d", h.BeaconBlockHeader.Slot), ProposerIndex: fmt.Sprintf("%d", h.BeaconBlockHeader.ProposerIndex), @@ -357,7 +342,7 @@ func (a *IndexedAttestation) MarshalJSON() ([]byte, error) { return json.Marshal(struct { AttestingIndices []string `json:"attesting_indices,omitempty"` Data *AttestationData - Signature hexSlice `json:"signature,omitempty"` + Signature hexutil.Bytes `json:"signature,omitempty"` }{ AttestingIndices: indices, Data: &AttestationData{a.IndexedAttestation.Data}, @@ -386,7 +371,7 @@ type Checkpoint struct { func (c *Checkpoint) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Epoch string `json:"epoch,omitempty"` - Root hexSlice `json:"root,omitempty"` + Root hexutil.Bytes `json:"root,omitempty"` }{ Epoch: fmt.Sprintf("%d", c.Checkpoint.Epoch), Root: c.Checkpoint.Root, @@ -401,7 +386,7 @@ func (a *AttestationData) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Slot string `json:"slot,omitempty"` Index string `json:"index,omitempty"` - BeaconBlockRoot hexSlice `json:"beacon_block_root,omitempty"` + BeaconBlockRoot hexutil.Bytes `json:"beacon_block_root,omitempty"` Source *Checkpoint `json:"source,omitempty"` Target *Checkpoint `json:"target,omitempty"` }{ @@ -419,11 +404,11 @@ type Attestation struct { func (a *Attestation) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - AggregationBits hexSlice `json:"aggregation_bits,omitempty"` + AggregationBits hexutil.Bytes `json:"aggregation_bits,omitempty"` Data *AttestationData `json:"data,omitempty"` - Signature hexSlice `json:"signature,omitempty" ssz-size:"96"` + Signature hexutil.Bytes `json:"signature,omitempty" ssz-size:"96"` }{ - AggregationBits: hexSlice(a.Attestation.AggregationBits), + AggregationBits: hexutil.Bytes(a.Attestation.AggregationBits), Data: &AttestationData{a.Attestation.Data}, Signature: a.Attestation.Signature, }) @@ -435,10 +420,10 @@ type DepositData struct { func (d *DepositData) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - PublicKey hexSlice `json:"pubkey,omitempty"` - WithdrawalCredentials hexSlice `json:"withdrawal_credentials,omitempty"` + PublicKey hexutil.Bytes `json:"pubkey,omitempty"` + WithdrawalCredentials hexutil.Bytes `json:"withdrawal_credentials,omitempty"` Amount string `json:"amount,omitempty"` - Signature hexSlice `json:"signature,omitempty"` + Signature hexutil.Bytes `json:"signature,omitempty"` }{ PublicKey: d.PublicKey, WithdrawalCredentials: d.WithdrawalCredentials, @@ -452,12 +437,12 @@ type Deposit struct { } func (d *Deposit) MarshalJSON() ([]byte, error) { - proof := make([]hexSlice, len(d.Proof)) + proof := make([]hexutil.Bytes, len(d.Proof)) for i := range d.Proof { proof[i] = d.Proof[i] } return json.Marshal(struct { - Proof []hexSlice `json:"proof"` + Proof []hexutil.Bytes `json:"proof"` Data *DepositData `json:"data"` }{ Proof: proof, @@ -472,7 +457,7 @@ type SignedVoluntaryExit struct { func (sve *SignedVoluntaryExit) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Message *VoluntaryExit `json:"message,omitempty"` - Signature hexSlice `json:"signature,omitempty"` + Signature hexutil.Bytes `json:"signature,omitempty"` }{ Signature: sve.SignedVoluntaryExit.Signature, Message: &VoluntaryExit{sve.SignedVoluntaryExit.Exit}, @@ -499,10 +484,10 @@ type SyncAggregate struct { func (s *SyncAggregate) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - SyncCommitteeBits hexSlice `json:"sync_committee_bits,omitempty"` - SyncCommitteeSignature hexSlice `json:"sync_committee_signature,omitempty"` + SyncCommitteeBits hexutil.Bytes `json:"sync_committee_bits,omitempty"` + SyncCommitteeSignature hexutil.Bytes `json:"sync_committee_signature,omitempty"` }{ - SyncCommitteeBits: hexSlice(s.SyncAggregate.SyncCommitteeBits), + SyncCommitteeBits: hexutil.Bytes(s.SyncAggregate.SyncCommitteeBits), SyncCommitteeSignature: s.SyncAggregate.SyncCommitteeSignature, }) } @@ -513,9 +498,9 @@ type Eth1Data struct { func (e *Eth1Data) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - DepositRoot hexSlice `json:"deposit_root,omitempty"` + DepositRoot hexutil.Bytes `json:"deposit_root,omitempty"` DepositCount string `json:"deposit_count,omitempty"` - BlockHash hexSlice `json:"block_hash,omitempty"` + BlockHash hexutil.Bytes `json:"block_hash,omitempty"` }{ DepositRoot: e.DepositRoot, DepositCount: fmt.Sprintf("%d", e.DepositCount), @@ -525,9 +510,9 @@ func (e *Eth1Data) MarshalJSON() ([]byte, error) { func (b *BlindedBeaconBlockBodyBellatrix) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - RandaoReveal hexSlice `json:"randao_reveal,omitempty"` + RandaoReveal hexutil.Bytes `json:"randao_reveal,omitempty"` Eth1Data *Eth1Data `json:"eth1_data,omitempty"` - Graffiti hexSlice `json:"graffiti,omitempty"` + Graffiti hexutil.Bytes `json:"graffiti,omitempty"` ProposerSlashings []*ProposerSlashing `json:"proposer_slashings,omitempty"` AttesterSlashings []*AttesterSlashing `json:"attester_slashings,omitempty"` Attestations []*Attestation `json:"attestations,omitempty"` diff --git a/api/client/builder/types_test.go b/api/client/builder/types_test.go index 034f4f31a000..31b3b110234f 100644 --- a/api/client/builder/types_test.go +++ b/api/client/builder/types_test.go @@ -83,12 +83,12 @@ func TestExecutionHeaderResponseUnmarshal(t *testing.T) { }{ { expected: "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", - actual: fmt.Sprintf("%#x", hr.Data.Signature), + actual: hexutil.Encode(hr.Data.Signature), name: "Signature", }, { expected: "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a", - actual: fmt.Sprintf("%#x", hr.Data.Message.Pubkey), + actual: hexutil.Encode(hr.Data.Message.Pubkey), name: "ExecHeaderResponse.Pubkey", }, { @@ -98,32 +98,32 @@ func TestExecutionHeaderResponseUnmarshal(t *testing.T) { }, { expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - actual: fmt.Sprintf("%#x", hr.Data.Message.Header.ParentHash), + actual: hexutil.Encode(hr.Data.Message.Header.ParentHash), name: "ExecHeaderResponse.ExecutionPayloadHeader.ParentHash", }, { expected: "0xabcf8e0d4e9587369b2301d0790347320302cc09", - actual: fmt.Sprintf("%#x", hr.Data.Message.Header.FeeRecipient), + actual: hexutil.Encode(hr.Data.Message.Header.FeeRecipient), name: "ExecHeaderResponse.ExecutionPayloadHeader.FeeRecipient", }, { expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - actual: fmt.Sprintf("%#x", hr.Data.Message.Header.StateRoot), + actual: hexutil.Encode(hr.Data.Message.Header.StateRoot), name: "ExecHeaderResponse.ExecutionPayloadHeader.StateRoot", }, { expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - actual: fmt.Sprintf("%#x", hr.Data.Message.Header.ReceiptsRoot), + actual: hexutil.Encode(hr.Data.Message.Header.ReceiptsRoot), name: "ExecHeaderResponse.ExecutionPayloadHeader.ReceiptsRoot", }, { expected: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - actual: fmt.Sprintf("%#x", hr.Data.Message.Header.LogsBloom), + actual: hexutil.Encode(hr.Data.Message.Header.LogsBloom), name: "ExecHeaderResponse.ExecutionPayloadHeader.LogsBloom", }, { expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - actual: fmt.Sprintf("%#x", hr.Data.Message.Header.PrevRandao), + actual: hexutil.Encode(hr.Data.Message.Header.PrevRandao), name: "ExecHeaderResponse.ExecutionPayloadHeader.PrevRandao", }, { @@ -148,7 +148,7 @@ func TestExecutionHeaderResponseUnmarshal(t *testing.T) { }, { expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - actual: fmt.Sprintf("%#x", hr.Data.Message.Header.ExtraData), + actual: hexutil.Encode(hr.Data.Message.Header.ExtraData), name: "ExecHeaderResponse.ExecutionPayloadHeader.ExtraData", }, { @@ -158,12 +158,12 @@ func TestExecutionHeaderResponseUnmarshal(t *testing.T) { }, { expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - actual: fmt.Sprintf("%#x", hr.Data.Message.Header.BlockHash), + actual: hexutil.Encode(hr.Data.Message.Header.BlockHash), name: "ExecHeaderResponse.ExecutionPayloadHeader.BlockHash", }, { expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - actual: fmt.Sprintf("%#x", hr.Data.Message.Header.TransactionsRoot), + actual: hexutil.Encode(hr.Data.Message.Header.TransactionsRoot), name: "ExecHeaderResponse.ExecutionPayloadHeader.TransactionsRoot", }, } @@ -262,32 +262,32 @@ func TestExecutionPayloadResponseUnmarshal(t *testing.T) { }{ { expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - actual: fmt.Sprintf("%#x", epr.Data.ParentHash), + actual: hexutil.Encode(epr.Data.ParentHash), name: "ExecPayloadResponse.ExecutionPayload.ParentHash", }, { expected: "0xabcf8e0d4e9587369b2301d0790347320302cc09", - actual: fmt.Sprintf("%#x", epr.Data.FeeRecipient), + actual: hexutil.Encode(epr.Data.FeeRecipient), name: "ExecPayloadResponse.ExecutionPayload.FeeRecipient", }, { expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - actual: fmt.Sprintf("%#x", epr.Data.StateRoot), + actual: hexutil.Encode(epr.Data.StateRoot), name: "ExecPayloadResponse.ExecutionPayload.StateRoot", }, { expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - actual: fmt.Sprintf("%#x", epr.Data.ReceiptsRoot), + actual: hexutil.Encode(epr.Data.ReceiptsRoot), name: "ExecPayloadResponse.ExecutionPayload.ReceiptsRoot", }, { expected: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - actual: fmt.Sprintf("%#x", epr.Data.LogsBloom), + actual: hexutil.Encode(epr.Data.LogsBloom), name: "ExecPayloadResponse.ExecutionPayload.LogsBloom", }, { expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - actual: fmt.Sprintf("%#x", epr.Data.PrevRandao), + actual: hexutil.Encode(epr.Data.PrevRandao), name: "ExecPayloadResponse.ExecutionPayload.PrevRandao", }, { @@ -312,7 +312,7 @@ func TestExecutionPayloadResponseUnmarshal(t *testing.T) { }, { expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - actual: fmt.Sprintf("%#x", epr.Data.ExtraData), + actual: hexutil.Encode(epr.Data.ExtraData), name: "ExecPayloadResponse.ExecutionPayload.ExtraData", }, { @@ -322,7 +322,7 @@ func TestExecutionPayloadResponseUnmarshal(t *testing.T) { }, { expected: "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - actual: fmt.Sprintf("%#x", epr.Data.BlockHash), + actual: hexutil.Encode(epr.Data.BlockHash), name: "ExecPayloadResponse.ExecutionPayload.BlockHash", }, } @@ -331,7 +331,7 @@ func TestExecutionPayloadResponseUnmarshal(t *testing.T) { } require.Equal(t, 1, len(epr.Data.Transactions)) txHash := "0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86" - require.Equal(t, txHash, fmt.Sprintf("%#x", epr.Data.Transactions[0])) + require.Equal(t, txHash, hexutil.Encode(epr.Data.Transactions[0])) } func TestExecutionPayloadResponseToProto(t *testing.T) { From 5c1d4dade1b78c645c89037b453047f60dc1dce0 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 10:52:46 -0500 Subject: [PATCH 05/21] use uint256 for BaseFeePerGas --- api/client/builder/types.go | 149 ++++++++++++++++--------------- api/client/builder/types_test.go | 62 ++++++------- 2 files changed, 107 insertions(+), 104 deletions(-) diff --git a/api/client/builder/types.go b/api/client/builder/types.go index c26675740a9f..34f6332effa9 100644 --- a/api/client/builder/types.go +++ b/api/client/builder/types.go @@ -23,7 +23,7 @@ type ValidatorRegistration struct { func (r *SignedValidatorRegistration) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Message *ValidatorRegistration `json:"message,omitempty"` - Signature hexutil.Bytes `json:"signature,omitempty"` + Signature hexutil.Bytes `json:"signature,omitempty"` }{ Message: &ValidatorRegistration{r.Message}, Signature: r.SignedValidatorRegistrationV1.Signature, @@ -33,16 +33,14 @@ func (r *SignedValidatorRegistration) MarshalJSON() ([]byte, error) { func (r *ValidatorRegistration) MarshalJSON() ([]byte, error) { return json.Marshal(struct { FeeRecipient hexutil.Bytes `json:"fee_recipient,omitempty"` - GasLimit string `json:"gas_limit,omitempty"` - Timestamp string `json:"timestamp,omitempty"` + GasLimit string `json:"gas_limit,omitempty"` + Timestamp string `json:"timestamp,omitempty"` Pubkey hexutil.Bytes `json:"pubkey,omitempty"` - *eth.ValidatorRegistrationV1 }{ - FeeRecipient: r.FeeRecipient, - GasLimit: fmt.Sprintf("%d", r.GasLimit), - Timestamp: fmt.Sprintf("%d", r.Timestamp), - Pubkey: r.Pubkey, - ValidatorRegistrationV1: r.ValidatorRegistrationV1, + FeeRecipient: r.FeeRecipient, + GasLimit: fmt.Sprintf("%d", r.GasLimit), + Timestamp: fmt.Sprintf("%d", r.Timestamp), + Pubkey: r.Pubkey, }) } @@ -76,8 +74,18 @@ func (s *Uint256) UnmarshalText(t []byte) error { return nil } +func (s Uint256) MarshalJSON() ([]byte, error) { + t, err := s.MarshalText() + if err != nil { + return nil, err + } + t = append([]byte{'"'}, t...) + t = append(t, '"') + return t, nil +} + func (s Uint256) MarshalText() ([]byte, error) { - return s.Bytes(), nil + return []byte(s.String()), nil } type Uint64String uint64 @@ -95,8 +103,8 @@ func (s Uint64String) MarshalText() ([]byte, error) { type ExecHeaderResponse struct { Version string `json:"version,omitempty"` Data struct { - Signature hexutil.Bytes `json:"signature,omitempty"` - Message *BuilderBid `json:"message,omitempty"` + Signature hexutil.Bytes `json:"signature,omitempty"` + Message *BuilderBid `json:"message,omitempty"` } `json:"data,omitempty"` } @@ -124,8 +132,6 @@ func (bb *BuilderBid) ToProto() (*eth.BuilderBid, error) { } func (h *ExecutionPayloadHeader) ToProto() (*eth.ExecutionPayloadHeader, error) { - // TODO: it looks like BaseFeePerGas should probably be a uint - baseFeeHack := []byte(strconv.FormatUint(uint64(h.BaseFeePerGas), 10)) return ð.ExecutionPayloadHeader{ ParentHash: h.ParentHash, FeeRecipient: h.FeeRecipient, @@ -138,7 +144,7 @@ func (h *ExecutionPayloadHeader) ToProto() (*eth.ExecutionPayloadHeader, error) GasUsed: uint64(h.GasUsed), Timestamp: uint64(h.Timestamp), ExtraData: h.ExtraData, - BaseFeePerGas: baseFeeHack, + BaseFeePerGas: h.BaseFeePerGas.Bytes(), BlockHash: h.BlockHash, TransactionsRoot: h.TransactionsRoot, }, nil @@ -147,33 +153,30 @@ func (h *ExecutionPayloadHeader) ToProto() (*eth.ExecutionPayloadHeader, error) type BuilderBid struct { Header *ExecutionPayloadHeader `json:"header,omitempty"` Value Uint256 `json:"value,omitempty"` - Pubkey hexutil.Bytes `json:"pubkey,omitempty"` + Pubkey hexutil.Bytes `json:"pubkey,omitempty"` } type ExecutionPayloadHeader struct { - ParentHash hexutil.Bytes `json:"parent_hash,omitempty"` - FeeRecipient hexutil.Bytes `json:"fee_recipient,omitempty"` - StateRoot hexutil.Bytes `json:"state_root,omitempty"` - ReceiptsRoot hexutil.Bytes `json:"receipts_root,omitempty"` - LogsBloom hexutil.Bytes `json:"logs_bloom,omitempty"` - PrevRandao hexutil.Bytes `json:"prev_randao,omitempty"` - BlockNumber Uint64String `json:"block_number,omitempty"` - GasLimit Uint64String `json:"gas_limit,omitempty"` - GasUsed Uint64String `json:"gas_used,omitempty"` - Timestamp Uint64String `json:"timestamp,omitempty"` - ExtraData hexutil.Bytes `json:"extra_data,omitempty"` - BaseFeePerGas Uint64String `json:"base_fee_per_gas,omitempty"` - BlockHash hexutil.Bytes `json:"block_hash,omitempty"` - TransactionsRoot hexutil.Bytes `json:"transactions_root,omitempty"` + ParentHash hexutil.Bytes `json:"parent_hash,omitempty"` + FeeRecipient hexutil.Bytes `json:"fee_recipient,omitempty"` + StateRoot hexutil.Bytes `json:"state_root,omitempty"` + ReceiptsRoot hexutil.Bytes `json:"receipts_root,omitempty"` + LogsBloom hexutil.Bytes `json:"logs_bloom,omitempty"` + PrevRandao hexutil.Bytes `json:"prev_randao,omitempty"` + BlockNumber Uint64String `json:"block_number,omitempty"` + GasLimit Uint64String `json:"gas_limit,omitempty"` + GasUsed Uint64String `json:"gas_used,omitempty"` + Timestamp Uint64String `json:"timestamp,omitempty"` + ExtraData hexutil.Bytes `json:"extra_data,omitempty"` + BaseFeePerGas Uint256 `json:"base_fee_per_gas,omitempty"` + BlockHash hexutil.Bytes `json:"block_hash,omitempty"` + TransactionsRoot hexutil.Bytes `json:"transactions_root,omitempty"` *eth.ExecutionPayloadHeader } func (h *ExecutionPayloadHeader) MarshalJSON() ([]byte, error) { - // TODO check this encoding and confirm bounds of values - bfpg, err := strconv.ParseUint(string(h.ExecutionPayloadHeader.BaseFeePerGas), 10, 64) - if err != nil { - return nil, err - } + bi := new(big.Int) + bfpg := Uint256{Int: bi.SetBytes(h.ExecutionPayloadHeader.BaseFeePerGas)} type MarshalCaller ExecutionPayloadHeader return json.Marshal(&MarshalCaller{ ParentHash: h.ExecutionPayloadHeader.ParentHash, @@ -187,7 +190,7 @@ func (h *ExecutionPayloadHeader) MarshalJSON() ([]byte, error) { GasUsed: Uint64String(h.ExecutionPayloadHeader.GasUsed), Timestamp: Uint64String(h.ExecutionPayloadHeader.Timestamp), ExtraData: h.ExecutionPayloadHeader.ExtraData, - BaseFeePerGas: Uint64String(bfpg), + BaseFeePerGas: bfpg, BlockHash: h.ExecutionPayloadHeader.BlockHash, TransactionsRoot: h.ExecutionPayloadHeader.TransactionsRoot, }) @@ -199,20 +202,20 @@ type ExecPayloadResponse struct { } type ExecutionPayload struct { - ParentHash hexutil.Bytes `json:"parent_hash,omitempty"` - FeeRecipient hexutil.Bytes `json:"fee_recipient,omitempty"` - StateRoot hexutil.Bytes `json:"state_root,omitempty"` - ReceiptsRoot hexutil.Bytes `json:"receipts_root,omitempty"` - LogsBloom hexutil.Bytes `json:"logs_bloom,omitempty"` - PrevRandao hexutil.Bytes `json:"prev_randao,omitempty"` - BlockNumber Uint64String `json:"block_number,omitempty"` - GasLimit Uint64String `json:"gas_limit,omitempty"` - GasUsed Uint64String `json:"gas_used,omitempty"` - Timestamp Uint64String `json:"timestamp,omitempty"` - ExtraData hexutil.Bytes `json:"extra_data,omitempty"` - BaseFeePerGas Uint64String `json:"base_fee_per_gas,omitempty"` - BlockHash hexutil.Bytes `json:"block_hash,omitempty"` - Transactions []hexutil.Bytes `json:"transactions,omitempty"` + ParentHash hexutil.Bytes `json:"parent_hash,omitempty"` + FeeRecipient hexutil.Bytes `json:"fee_recipient,omitempty"` + StateRoot hexutil.Bytes `json:"state_root,omitempty"` + ReceiptsRoot hexutil.Bytes `json:"receipts_root,omitempty"` + LogsBloom hexutil.Bytes `json:"logs_bloom,omitempty"` + PrevRandao hexutil.Bytes `json:"prev_randao,omitempty"` + BlockNumber Uint64String `json:"block_number,omitempty"` + GasLimit Uint64String `json:"gas_limit,omitempty"` + GasUsed Uint64String `json:"gas_used,omitempty"` + Timestamp Uint64String `json:"timestamp,omitempty"` + ExtraData hexutil.Bytes `json:"extra_data,omitempty"` + BaseFeePerGas Uint256 `json:"base_fee_per_gas,omitempty"` + BlockHash hexutil.Bytes `json:"block_hash,omitempty"` + Transactions []hexutil.Bytes `json:"transactions,omitempty"` } func (r *ExecPayloadResponse) ToProto() (*v1.ExecutionPayload, error) { @@ -220,8 +223,6 @@ func (r *ExecPayloadResponse) ToProto() (*v1.ExecutionPayload, error) { } func (p *ExecutionPayload) ToProto() (*v1.ExecutionPayload, error) { - // TODO: it looks like BaseFeePerGas should probably be a uint - baseFeeHack := []byte(strconv.FormatUint(uint64(p.BaseFeePerGas), 10)) txs := make([][]byte, len(p.Transactions)) for i := range p.Transactions { txs[i] = p.Transactions[i] @@ -238,7 +239,7 @@ func (p *ExecutionPayload) ToProto() (*v1.ExecutionPayload, error) { GasUsed: uint64(p.GasUsed), Timestamp: uint64(p.Timestamp), ExtraData: p.ExtraData, - BaseFeePerGas: baseFeeHack, + BaseFeePerGas: p.BaseFeePerGas.Bytes(), BlockHash: p.BlockHash, Transactions: txs, }, nil @@ -259,7 +260,7 @@ type BlindedBeaconBlockBodyBellatrix struct { func (r *SignedBlindedBeaconBlockBellatrix) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Message *BlindedBeaconBlockBellatrix `json:"message,omitempty"` - Signature hexutil.Bytes `json:"signature,omitempty"` + Signature hexutil.Bytes `json:"signature,omitempty"` }{ Message: &BlindedBeaconBlockBellatrix{r.SignedBlindedBeaconBlockBellatrix.Block}, Signature: r.SignedBlindedBeaconBlockBellatrix.Signature, @@ -270,8 +271,8 @@ func (b *BlindedBeaconBlockBellatrix) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Slot string `json:"slot"` ProposerIndex string `json:"proposer_index,omitempty"` - ParentRoot hexutil.Bytes `json:"parent_root,omitempty"` - StateRoot hexutil.Bytes `json:"state_root,omitempty"` + ParentRoot hexutil.Bytes `json:"parent_root,omitempty"` + StateRoot hexutil.Bytes `json:"state_root,omitempty"` Body *BlindedBeaconBlockBodyBellatrix `json:"body,omitempty"` }{ Slot: fmt.Sprintf("%d", b.Slot), @@ -303,7 +304,7 @@ type SignedBeaconBlockHeader struct { func (h *SignedBeaconBlockHeader) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Header *BeaconBlockHeader `json:"message,omitempty"` - Signature hexutil.Bytes `json:"signature,omitempty"` + Signature hexutil.Bytes `json:"signature,omitempty"` }{ Header: &BeaconBlockHeader{h.SignedBeaconBlockHeader.Header}, Signature: h.SignedBeaconBlockHeader.Signature, @@ -316,8 +317,8 @@ type BeaconBlockHeader struct { func (h *BeaconBlockHeader) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - Slot string `json:"slot,omitempty"` - ProposerIndex string `json:"proposer_index,omitempty"` + Slot string `json:"slot,omitempty"` + ProposerIndex string `json:"proposer_index,omitempty"` ParentRoot hexutil.Bytes `json:"parent_root,omitempty"` StateRoot hexutil.Bytes `json:"state_root,omitempty"` BodyRoot hexutil.Bytes `json:"body_root,omitempty"` @@ -370,7 +371,7 @@ type Checkpoint struct { func (c *Checkpoint) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - Epoch string `json:"epoch,omitempty"` + Epoch string `json:"epoch,omitempty"` Root hexutil.Bytes `json:"root,omitempty"` }{ Epoch: fmt.Sprintf("%d", c.Checkpoint.Epoch), @@ -384,11 +385,11 @@ type AttestationData struct { func (a *AttestationData) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - Slot string `json:"slot,omitempty"` - Index string `json:"index,omitempty"` - BeaconBlockRoot hexutil.Bytes `json:"beacon_block_root,omitempty"` - Source *Checkpoint `json:"source,omitempty"` - Target *Checkpoint `json:"target,omitempty"` + Slot string `json:"slot,omitempty"` + Index string `json:"index,omitempty"` + BeaconBlockRoot hexutil.Bytes `json:"beacon_block_root,omitempty"` + Source *Checkpoint `json:"source,omitempty"` + Target *Checkpoint `json:"target,omitempty"` }{ Slot: fmt.Sprintf("%d", a.AttestationData.Slot), Index: fmt.Sprintf("%d", a.AttestationData.CommitteeIndex), @@ -404,9 +405,9 @@ type Attestation struct { func (a *Attestation) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - AggregationBits hexutil.Bytes `json:"aggregation_bits,omitempty"` + AggregationBits hexutil.Bytes `json:"aggregation_bits,omitempty"` Data *AttestationData `json:"data,omitempty"` - Signature hexutil.Bytes `json:"signature,omitempty" ssz-size:"96"` + Signature hexutil.Bytes `json:"signature,omitempty" ssz-size:"96"` }{ AggregationBits: hexutil.Bytes(a.Attestation.AggregationBits), Data: &AttestationData{a.Attestation.Data}, @@ -422,7 +423,7 @@ func (d *DepositData) MarshalJSON() ([]byte, error) { return json.Marshal(struct { PublicKey hexutil.Bytes `json:"pubkey,omitempty"` WithdrawalCredentials hexutil.Bytes `json:"withdrawal_credentials,omitempty"` - Amount string `json:"amount,omitempty"` + Amount string `json:"amount,omitempty"` Signature hexutil.Bytes `json:"signature,omitempty"` }{ PublicKey: d.PublicKey, @@ -442,8 +443,8 @@ func (d *Deposit) MarshalJSON() ([]byte, error) { proof[i] = d.Proof[i] } return json.Marshal(struct { - Proof []hexutil.Bytes `json:"proof"` - Data *DepositData `json:"data"` + Proof []hexutil.Bytes `json:"proof"` + Data *DepositData `json:"data"` }{ Proof: proof, Data: &DepositData{Deposit_Data: d.Deposit.Data}, @@ -457,7 +458,7 @@ type SignedVoluntaryExit struct { func (sve *SignedVoluntaryExit) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Message *VoluntaryExit `json:"message,omitempty"` - Signature hexutil.Bytes `json:"signature,omitempty"` + Signature hexutil.Bytes `json:"signature,omitempty"` }{ Signature: sve.SignedVoluntaryExit.Signature, Message: &VoluntaryExit{sve.SignedVoluntaryExit.Exit}, @@ -499,7 +500,7 @@ type Eth1Data struct { func (e *Eth1Data) MarshalJSON() ([]byte, error) { return json.Marshal(struct { DepositRoot hexutil.Bytes `json:"deposit_root,omitempty"` - DepositCount string `json:"deposit_count,omitempty"` + DepositCount string `json:"deposit_count,omitempty"` BlockHash hexutil.Bytes `json:"block_hash,omitempty"` }{ DepositRoot: e.DepositRoot, @@ -510,9 +511,9 @@ func (e *Eth1Data) MarshalJSON() ([]byte, error) { func (b *BlindedBeaconBlockBodyBellatrix) MarshalJSON() ([]byte, error) { return json.Marshal(struct { - RandaoReveal hexutil.Bytes `json:"randao_reveal,omitempty"` + RandaoReveal hexutil.Bytes `json:"randao_reveal,omitempty"` Eth1Data *Eth1Data `json:"eth1_data,omitempty"` - Graffiti hexutil.Bytes `json:"graffiti,omitempty"` + Graffiti hexutil.Bytes `json:"graffiti,omitempty"` ProposerSlashings []*ProposerSlashing `json:"proposer_slashings,omitempty"` AttesterSlashings []*AttesterSlashing `json:"attester_slashings,omitempty"` Attestations []*Attestation `json:"attestations,omitempty"` diff --git a/api/client/builder/types_test.go b/api/client/builder/types_test.go index 31b3b110234f..746a32ffbb76 100644 --- a/api/client/builder/types_test.go +++ b/api/client/builder/types_test.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "math/big" - "strconv" "testing" "github.com/ethereum/go-ethereum/common/hexutil" @@ -202,26 +201,27 @@ func TestExecutionHeaderResponseToProto(t *testing.T) { value := big.NewInt(0) value, ok := value.SetString("1", 10) require.Equal(t, true, ok) + + bi := new(big.Int) + bfpg := Uint256{Int: bi.SetUint64(1)} expected := ð.SignedBuilderBid{ Message: ð.BuilderBid{ Header: ð.ExecutionPayloadHeader{ - ParentHash: parentHash, - FeeRecipient: feeRecipient, - StateRoot: stateRoot, - ReceiptsRoot: receiptsRoot, - LogsBloom: logsBloom, - PrevRandao: prevRandao, - BlockNumber: 1, - GasLimit: 1, - GasUsed: 1, - Timestamp: 1, - ExtraData: extraData, - // TODO assumes weird byte slice field - BaseFeePerGas: []byte(strconv.FormatUint(uint64(1), 10)), + ParentHash: parentHash, + FeeRecipient: feeRecipient, + StateRoot: stateRoot, + ReceiptsRoot: receiptsRoot, + LogsBloom: logsBloom, + PrevRandao: prevRandao, + BlockNumber: 1, + GasLimit: 1, + GasUsed: 1, + Timestamp: 1, + ExtraData: extraData, + BaseFeePerGas: bfpg.Bytes(), BlockHash: blockHash, TransactionsRoot: txRoot, }, - // TODO assumes weird byte slice field Value: value.Bytes(), Pubkey: pubkey, }, @@ -361,20 +361,21 @@ func TestExecutionPayloadResponseToProto(t *testing.T) { require.NoError(t, err) txList := [][]byte{tx} + bi := new(big.Int) + bfpg := Uint256{Int: bi.SetUint64(1)} expected := &v1.ExecutionPayload{ - ParentHash: parentHash, - FeeRecipient: feeRecipient, - StateRoot: stateRoot, - ReceiptsRoot: receiptsRoot, - LogsBloom: logsBloom, - PrevRandao: prevRandao, - BlockNumber: 1, - GasLimit: 1, - GasUsed: 1, - Timestamp: 1, - ExtraData: extraData, - // TODO assumes weird byte slice field - BaseFeePerGas: []byte(strconv.FormatUint(uint64(1), 10)), + ParentHash: parentHash, + FeeRecipient: feeRecipient, + StateRoot: stateRoot, + ReceiptsRoot: receiptsRoot, + LogsBloom: logsBloom, + PrevRandao: prevRandao, + BlockNumber: 1, + GasLimit: 1, + GasUsed: 1, + Timestamp: 1, + ExtraData: extraData, + BaseFeePerGas: bfpg.Bytes(), BlockHash: blockHash, Transactions: txList, } @@ -543,7 +544,8 @@ func TestProposerSlashings(t *testing.T) { } func TestExecutionPayloadHeader_MarshalJSON(t *testing.T) { - bfpg := []byte(strconv.FormatUint(1, 10)) + bi := new(big.Int) + bfpg := Uint256{Int: bi.SetUint64(1)} h := &ExecutionPayloadHeader{ ExecutionPayloadHeader: ð.ExecutionPayloadHeader{ ParentHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), @@ -557,7 +559,7 @@ func TestExecutionPayloadHeader_MarshalJSON(t *testing.T) { GasUsed: 1, Timestamp: 1, ExtraData: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - BaseFeePerGas: bfpg, + BaseFeePerGas: bfpg.Bytes(), BlockHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), TransactionsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), }, From b7c33888d2168ac7481aeee98e8046630755fff3 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 11:28:45 -0500 Subject: [PATCH 06/21] more confidence in correct endianness --- api/client/builder/BUILD.bazel | 1 + api/client/builder/types.go | 27 ++++++++++++++++++++--- api/client/builder/types_test.go | 37 +++++++++++++++++++------------- 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/api/client/builder/BUILD.bazel b/api/client/builder/BUILD.bazel index 9790f4ac6e5b..b786f577ade0 100644 --- a/api/client/builder/BUILD.bazel +++ b/api/client/builder/BUILD.bazel @@ -11,6 +11,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//consensus-types/primitives:go_default_library", + "//encoding/bytesutil:go_default_library", "//proto/engine/v1:go_default_library", "//proto/prysm/v1alpha1:go_default_library", "@com_github_ethereum_go_ethereum//common/hexutil:go_default_library", diff --git a/api/client/builder/types.go b/api/client/builder/types.go index 34f6332effa9..4143b4e30b61 100644 --- a/api/client/builder/types.go +++ b/api/client/builder/types.go @@ -6,6 +6,7 @@ import ( "math/big" "strconv" + "github.com/prysmaticlabs/prysm/encoding/bytesutil" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" v1 "github.com/prysmaticlabs/prysm/proto/engine/v1" @@ -48,6 +49,28 @@ type Uint256 struct { *big.Int } +func stringToUint256(s string) Uint256 { + bi := new(big.Int) + bi.SetString(s, 10) + return Uint256{Int: bi} +} + +func uint64ToUint256(u uint64) Uint256 { + bi := new(big.Int) + return Uint256{Int: bi.SetUint64(u)} +} + +// sszBytesToUint256 creates a Uint256 from a ssz-style (little-endian byte slice) representation. +func sszBytesToUint256(b []byte) Uint256 { + bi := new(big.Int) + return Uint256{Int: bi.SetBytes(bytesutil.ReverseByteOrder(b))} +} + +// SSZBytes creates an ssz-style (little-endian byte slice) representation of the Uint256 +func (s Uint256) SSZBytes() []byte { + return bytesutil.ReverseByteOrder(s.Int.Bytes()) +} + var errUnmarshalUint256Failed = errors.New("unable to UnmarshalText into a Uint256 value") func (s *Uint256) UnmarshalJSON(t []byte) error { @@ -175,8 +198,6 @@ type ExecutionPayloadHeader struct { } func (h *ExecutionPayloadHeader) MarshalJSON() ([]byte, error) { - bi := new(big.Int) - bfpg := Uint256{Int: bi.SetBytes(h.ExecutionPayloadHeader.BaseFeePerGas)} type MarshalCaller ExecutionPayloadHeader return json.Marshal(&MarshalCaller{ ParentHash: h.ExecutionPayloadHeader.ParentHash, @@ -190,7 +211,7 @@ func (h *ExecutionPayloadHeader) MarshalJSON() ([]byte, error) { GasUsed: Uint64String(h.ExecutionPayloadHeader.GasUsed), Timestamp: Uint64String(h.ExecutionPayloadHeader.Timestamp), ExtraData: h.ExecutionPayloadHeader.ExtraData, - BaseFeePerGas: bfpg, + BaseFeePerGas: sszBytesToUint256(h.ExecutionPayloadHeader.BaseFeePerGas), BlockHash: h.ExecutionPayloadHeader.BlockHash, TransactionsRoot: h.ExecutionPayloadHeader.TransactionsRoot, }) diff --git a/api/client/builder/types_test.go b/api/client/builder/types_test.go index 746a32ffbb76..83b3377f2779 100644 --- a/api/client/builder/types_test.go +++ b/api/client/builder/types_test.go @@ -198,12 +198,7 @@ func TestExecutionHeaderResponseToProto(t *testing.T) { require.NoError(t, err) txRoot, err := hexutil.Decode("0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") require.NoError(t, err) - value := big.NewInt(0) - value, ok := value.SetString("1", 10) - require.Equal(t, true, ok) - bi := new(big.Int) - bfpg := Uint256{Int: bi.SetUint64(1)} expected := ð.SignedBuilderBid{ Message: ð.BuilderBid{ Header: ð.ExecutionPayloadHeader{ @@ -218,11 +213,11 @@ func TestExecutionHeaderResponseToProto(t *testing.T) { GasUsed: 1, Timestamp: 1, ExtraData: extraData, - BaseFeePerGas: bfpg.Bytes(), + BaseFeePerGas: uint64ToUint256(1).SSZBytes(), BlockHash: blockHash, TransactionsRoot: txRoot, }, - Value: value.Bytes(), + Value: uint64ToUint256(1).SSZBytes(), Pubkey: pubkey, }, Signature: signature, @@ -361,8 +356,6 @@ func TestExecutionPayloadResponseToProto(t *testing.T) { require.NoError(t, err) txList := [][]byte{tx} - bi := new(big.Int) - bfpg := Uint256{Int: bi.SetUint64(1)} expected := &v1.ExecutionPayload{ ParentHash: parentHash, FeeRecipient: feeRecipient, @@ -375,7 +368,7 @@ func TestExecutionPayloadResponseToProto(t *testing.T) { GasUsed: 1, Timestamp: 1, ExtraData: extraData, - BaseFeePerGas: bfpg.Bytes(), + BaseFeePerGas: uint64ToUint256(1).SSZBytes(), BlockHash: blockHash, Transactions: txList, } @@ -544,8 +537,7 @@ func TestProposerSlashings(t *testing.T) { } func TestExecutionPayloadHeader_MarshalJSON(t *testing.T) { - bi := new(big.Int) - bfpg := Uint256{Int: bi.SetUint64(1)} + bfpg := stringToUint256("452312848583266388373324160190187140051835877600158453279131187530910662656") h := &ExecutionPayloadHeader{ ExecutionPayloadHeader: ð.ExecutionPayloadHeader{ ParentHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), @@ -559,14 +551,14 @@ func TestExecutionPayloadHeader_MarshalJSON(t *testing.T) { GasUsed: 1, Timestamp: 1, ExtraData: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - BaseFeePerGas: bfpg.Bytes(), + BaseFeePerGas: bfpg.SSZBytes(), BlockHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), TransactionsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), }, } b, err := json.Marshal(h) require.NoError(t, err) - expected := `{"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","block_hash":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","transactions_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}` + expected := `{"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":"452312848583266388373324160190187140051835877600158453279131187530910662656","block_hash":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","transactions_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}` require.Equal(t, expected, string(b)) } @@ -619,5 +611,20 @@ func TestMathBigUnmarshal(t *testing.T) { var u256 Uint256 require.NoError(t, u256.UnmarshalText([]byte("452312848583266388373324160190187140051835877600158453279131187530910662656"))) - t.Logf("%v", u256.Bytes()) +} + +func TestUint256Unmarshal(t *testing.T) { + base10 := "452312848583266388373324160190187140051835877600158453279131187530910662656" + bi := new(big.Int) + bi, ok := bi.SetString(base10, 10) + require.Equal(t, true, ok) + s := struct { + BigNumber Uint256 `json:"big_number"` + }{ + BigNumber: Uint256{Int: bi}, + } + m, err := json.Marshal(s) + require.NoError(t, err) + expected := `{"big_number":"452312848583266388373324160190187140051835877600158453279131187530910662656"}` + require.Equal(t, expected, string(m)) } From 5a7c260c82f7132332095a55818892f388c4b313 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 11:29:55 -0500 Subject: [PATCH 07/21] comment fix per Terence --- api/client/builder/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client/builder/client.go b/api/client/builder/client.go index 61f697e2d2fc..27e1f4240820 100644 --- a/api/client/builder/client.go +++ b/api/client/builder/client.go @@ -39,7 +39,7 @@ func WithTimeout(timeout time.Duration) ClientOpt { } } -// Client provides a collection of helper methods for calling the Eth Beacon Node API endpoints. +// Client provides a collection of helper methods for calling Builder API endpoints. type Client struct { hc *http.Client baseURL *url.URL From 3fd0802db865db1e656b53b7a79ce858602f7456 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 12:12:20 -0500 Subject: [PATCH 08/21] fix proto conversion for uint256 --- api/client/builder/client_test.go | 4 ++++ api/client/builder/types.go | 8 ++++---- api/client/builder/types_test.go | 14 ++++++++------ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/api/client/builder/client_test.go b/api/client/builder/client_test.go index 612a22f13f77..6b801609539b 100644 --- a/api/client/builder/client_test.go +++ b/api/client/builder/client_test.go @@ -3,6 +3,7 @@ package builder import ( "bytes" "context" + "fmt" "io" "net/http" "net/url" @@ -149,6 +150,9 @@ func TestClient_GetHeader(t *testing.T) { require.Equal(t, true, bytes.Equal(expectedSig, h.Signature)) expectedTxRoot := ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") require.Equal(t, true, bytes.Equal(expectedTxRoot, h.Message.Header.TransactionsRoot)) + require.Equal(t, uint64(1), h.Message.Header.GasUsed) + bfpg := stringToUint256("452312848583266388373324160190187140051835877600158453279131187530910662656") + require.Equal(t, fmt.Sprintf("%#x", bfpg.SSZBytes()), fmt.Sprintf("%#x", h.Message.Header.BaseFeePerGas)) } func TestSubmitBlindedBlock(t *testing.T) { diff --git a/api/client/builder/types.go b/api/client/builder/types.go index 4143b4e30b61..1c365f02a5d4 100644 --- a/api/client/builder/types.go +++ b/api/client/builder/types.go @@ -6,9 +6,9 @@ import ( "math/big" "strconv" - "github.com/prysmaticlabs/prysm/encoding/bytesutil" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/encoding/bytesutil" v1 "github.com/prysmaticlabs/prysm/proto/engine/v1" eth "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1" ) @@ -149,7 +149,7 @@ func (bb *BuilderBid) ToProto() (*eth.BuilderBid, error) { } return ð.BuilderBid{ Header: header, - Value: bb.Value.Bytes(), + Value: bb.Value.SSZBytes(), Pubkey: bb.Pubkey, }, nil } @@ -167,7 +167,7 @@ func (h *ExecutionPayloadHeader) ToProto() (*eth.ExecutionPayloadHeader, error) GasUsed: uint64(h.GasUsed), Timestamp: uint64(h.Timestamp), ExtraData: h.ExtraData, - BaseFeePerGas: h.BaseFeePerGas.Bytes(), + BaseFeePerGas: h.BaseFeePerGas.SSZBytes(), BlockHash: h.BlockHash, TransactionsRoot: h.TransactionsRoot, }, nil @@ -260,7 +260,7 @@ func (p *ExecutionPayload) ToProto() (*v1.ExecutionPayload, error) { GasUsed: uint64(p.GasUsed), Timestamp: uint64(p.Timestamp), ExtraData: p.ExtraData, - BaseFeePerGas: p.BaseFeePerGas.Bytes(), + BaseFeePerGas: p.BaseFeePerGas.SSZBytes(), BlockHash: p.BlockHash, Transactions: txs, }, nil diff --git a/api/client/builder/types_test.go b/api/client/builder/types_test.go index 83b3377f2779..a57541f9ceef 100644 --- a/api/client/builder/types_test.go +++ b/api/client/builder/types_test.go @@ -61,11 +61,11 @@ var testExampleHeaderResponse = `{ "gas_used": "1", "timestamp": "1", "extra_data": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "base_fee_per_gas": "1", + "base_fee_per_gas": "452312848583266388373324160190187140051835877600158453279131187530910662656", "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "transactions_root": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2" }, - "value": "1", + "value": "652312848583266388373324160190187140051835877600158453279131187530910662656", "pubkey": "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a" }, "signature": "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505" @@ -91,7 +91,7 @@ func TestExecutionHeaderResponseUnmarshal(t *testing.T) { name: "ExecHeaderResponse.Pubkey", }, { - expected: "1", + expected: "652312848583266388373324160190187140051835877600158453279131187530910662656", actual: hr.Data.Message.Value.String(), name: "ExecHeaderResponse.Value", }, @@ -151,7 +151,7 @@ func TestExecutionHeaderResponseUnmarshal(t *testing.T) { name: "ExecHeaderResponse.ExecutionPayloadHeader.ExtraData", }, { - expected: "1", + expected: "452312848583266388373324160190187140051835877600158453279131187530910662656", actual: fmt.Sprintf("%d", hr.Data.Message.Header.BaseFeePerGas), name: "ExecHeaderResponse.ExecutionPayloadHeader.BaseFeePerGas", }, @@ -172,6 +172,8 @@ func TestExecutionHeaderResponseUnmarshal(t *testing.T) { } func TestExecutionHeaderResponseToProto(t *testing.T) { + bfpg := stringToUint256("452312848583266388373324160190187140051835877600158453279131187530910662656") + v := stringToUint256("652312848583266388373324160190187140051835877600158453279131187530910662656") hr := &ExecHeaderResponse{} require.NoError(t, json.Unmarshal([]byte(testExampleHeaderResponse), hr)) p, err := hr.ToProto() @@ -213,11 +215,11 @@ func TestExecutionHeaderResponseToProto(t *testing.T) { GasUsed: 1, Timestamp: 1, ExtraData: extraData, - BaseFeePerGas: uint64ToUint256(1).SSZBytes(), + BaseFeePerGas: bfpg.SSZBytes(), BlockHash: blockHash, TransactionsRoot: txRoot, }, - Value: uint64ToUint256(1).SSZBytes(), + Value: v.SSZBytes(), Pubkey: pubkey, }, Signature: signature, From 1750c084799ef78a0425adb92d6704069a0b278b Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 12:18:59 -0500 Subject: [PATCH 09/21] couple more value checks in the http client tests --- api/client/builder/client_test.go | 7 +++++-- api/client/builder/types_test.go | 7 ++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/api/client/builder/client_test.go b/api/client/builder/client_test.go index 6b801609539b..0fe489de5f42 100644 --- a/api/client/builder/client_test.go +++ b/api/client/builder/client_test.go @@ -151,8 +151,8 @@ func TestClient_GetHeader(t *testing.T) { expectedTxRoot := ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2") require.Equal(t, true, bytes.Equal(expectedTxRoot, h.Message.Header.TransactionsRoot)) require.Equal(t, uint64(1), h.Message.Header.GasUsed) - bfpg := stringToUint256("452312848583266388373324160190187140051835877600158453279131187530910662656") - require.Equal(t, fmt.Sprintf("%#x", bfpg.SSZBytes()), fmt.Sprintf("%#x", h.Message.Header.BaseFeePerGas)) + value := stringToUint256("652312848583266388373324160190187140051835877600158453279131187530910662656") + require.Equal(t, fmt.Sprintf("%#x", value.SSZBytes()), fmt.Sprintf("%#x", h.Message.Value)) } func TestSubmitBlindedBlock(t *testing.T) { @@ -175,6 +175,9 @@ func TestSubmitBlindedBlock(t *testing.T) { ep, err := c.SubmitBlindedBlock(ctx, sbbb) require.NoError(t, err) require.Equal(t, true, bytes.Equal(ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), ep.ParentHash)) + bfpg := stringToUint256("452312848583266388373324160190187140051835877600158453279131187530910662656") + require.Equal(t, fmt.Sprintf("%#x", bfpg.SSZBytes()), fmt.Sprintf("%#x", ep.BaseFeePerGas)) + require.Equal(t, uint64(1), ep.GasLimit) } func testSignedBlindedBeaconBlockBellatrix(t *testing.T) *eth.SignedBlindedBeaconBlockBellatrix { diff --git a/api/client/builder/types_test.go b/api/client/builder/types_test.go index a57541f9ceef..98978dbea990 100644 --- a/api/client/builder/types_test.go +++ b/api/client/builder/types_test.go @@ -241,7 +241,7 @@ var testExampleExecutionPayload = `{ "gas_used": "1", "timestamp": "1", "extra_data": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", - "base_fee_per_gas": "1", + "base_fee_per_gas": "452312848583266388373324160190187140051835877600158453279131187530910662656", "block_hash": "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2", "transactions": [ "0x02f878831469668303f51d843b9ac9f9843b9aca0082520894c93269b73096998db66be0441e836d873535cb9c8894a19041886f000080c001a031cc29234036afbf9a1fb9476b463367cb1f957ac0b919b69bbc798436e604aaa018c4e9c3914eb27aadd0b91e10b18655739fcf8c1fc398763a9f1beecb8ddc86" @@ -313,7 +313,7 @@ func TestExecutionPayloadResponseUnmarshal(t *testing.T) { name: "ExecPayloadResponse.ExecutionPayload.ExtraData", }, { - expected: "1", + expected: "452312848583266388373324160190187140051835877600158453279131187530910662656", actual: fmt.Sprintf("%d", epr.Data.BaseFeePerGas), name: "ExecPayloadResponse.ExecutionPayload.BaseFeePerGas", }, @@ -358,6 +358,7 @@ func TestExecutionPayloadResponseToProto(t *testing.T) { require.NoError(t, err) txList := [][]byte{tx} + bfpg := stringToUint256("452312848583266388373324160190187140051835877600158453279131187530910662656") expected := &v1.ExecutionPayload{ ParentHash: parentHash, FeeRecipient: feeRecipient, @@ -370,7 +371,7 @@ func TestExecutionPayloadResponseToProto(t *testing.T) { GasUsed: 1, Timestamp: 1, ExtraData: extraData, - BaseFeePerGas: uint64ToUint256(1).SSZBytes(), + BaseFeePerGas: bfpg.SSZBytes(), BlockHash: blockHash, Transactions: txList, } From 50e4d3df111f0fb9ccd57491e9f85905118e9980 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 13:22:19 -0500 Subject: [PATCH 10/21] TestMarshalBlindedBeaconBlockBodyBellatrix --- api/client/builder/BUILD.bazel | 1 + .../builder/testdata/blinded-block.json | 1 + api/client/builder/types.go | 44 +++- api/client/builder/types_test.go | 242 +++++++++++------- 4 files changed, 183 insertions(+), 105 deletions(-) create mode 100644 api/client/builder/testdata/blinded-block.json diff --git a/api/client/builder/BUILD.bazel b/api/client/builder/BUILD.bazel index b786f577ade0..08495fee16a0 100644 --- a/api/client/builder/BUILD.bazel +++ b/api/client/builder/BUILD.bazel @@ -26,6 +26,7 @@ go_test( "client_test.go", "types_test.go", ], + data = glob(["testdata/**"]), embed = [":go_default_library"], deps = [ "//config/fieldparams:go_default_library", diff --git a/api/client/builder/testdata/blinded-block.json b/api/client/builder/testdata/blinded-block.json new file mode 100644 index 000000000000..207f5d5c5a28 --- /dev/null +++ b/api/client/builder/testdata/blinded-block.json @@ -0,0 +1 @@ +{"slot":"1","proposer_index":"1","parent_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","state_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","body":{"randao_reveal":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505","eth1_data":{"deposit_root":"0x0000000000000000000000000000000000000000000000000000000000000000","deposit_count":"23","block_hash":"0x0000000000000000000000000000000000000000000000000000000000000000"},"graffiti":"0xdeadbeefc0ffee","proposer_slashings":[{"signed_header_1":{"message":{"slot":"1","proposer_index":"1","parent_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","state_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","body_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"},"signed_header_2":{"message":{"slot":"1","proposer_index":"1","parent_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","state_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","body_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}}],"attester_slashings":[{"attestation_1":{"attesting_indices":["1"],"data":{"slot":"1","index":"1","beacon_block_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","source":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"target":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"},"attestation_2":{"attesting_indices":["1"],"data":{"slot":"1","index":"1","beacon_block_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","source":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"target":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}}],"attestations":[{"aggregation_bits":"0x01","data":{"slot":"1","index":"1","beacon_block_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","source":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"target":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}],"deposits":[{"proof":["0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"],"data":{"pubkey":"0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a","withdrawal_credentials":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","amount":"1","signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}}],"voluntary_exits":[{"message":{"epoch":"1","validator_index":"1"},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}],"sync_aggregate":{"sync_committee_bits":"0x01","sync_committee_signature":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"execution_payload_header":{"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":"452312848583266388373324160190187140051835877600158453279131187530910662656","block_hash":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","transactions_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}}} diff --git a/api/client/builder/types.go b/api/client/builder/types.go index 1c365f02a5d4..4d065335393a 100644 --- a/api/client/builder/types.go +++ b/api/client/builder/types.go @@ -55,11 +55,6 @@ func stringToUint256(s string) Uint256 { return Uint256{Int: bi} } -func uint64ToUint256(u uint64) Uint256 { - bi := new(big.Int) - return Uint256{Int: bi.SetUint64(u)} -} - // sszBytesToUint256 creates a Uint256 from a ssz-style (little-endian byte slice) representation. func sszBytesToUint256(b []byte) Uint256 { bi := new(big.Int) @@ -362,9 +357,9 @@ func (a *IndexedAttestation) MarshalJSON() ([]byte, error) { indices[i] = fmt.Sprintf("%d", a.AttestingIndices[i]) } return json.Marshal(struct { - AttestingIndices []string `json:"attesting_indices,omitempty"` - Data *AttestationData - Signature hexutil.Bytes `json:"signature,omitempty"` + AttestingIndices []string `json:"attesting_indices,omitempty"` + Data *AttestationData `json:"data,omitempty"` + Signature hexutil.Bytes `json:"signature,omitempty"` }{ AttestingIndices: indices, Data: &AttestationData{a.IndexedAttestation.Data}, @@ -531,6 +526,26 @@ func (e *Eth1Data) MarshalJSON() ([]byte, error) { } func (b *BlindedBeaconBlockBodyBellatrix) MarshalJSON() ([]byte, error) { + sve := make([]*SignedVoluntaryExit, len(b.BlindedBeaconBlockBodyBellatrix.VoluntaryExits)) + for i := range b.BlindedBeaconBlockBodyBellatrix.VoluntaryExits { + sve[i] = &SignedVoluntaryExit{SignedVoluntaryExit: b.BlindedBeaconBlockBodyBellatrix.VoluntaryExits[i]} + } + deps := make([]*Deposit, len(b.BlindedBeaconBlockBodyBellatrix.Deposits)) + for i := range b.BlindedBeaconBlockBodyBellatrix.Deposits { + deps[i] = &Deposit{Deposit: b.BlindedBeaconBlockBodyBellatrix.Deposits[i]} + } + atts := make([]*Attestation, len(b.BlindedBeaconBlockBodyBellatrix.Attestations)) + for i := range b.BlindedBeaconBlockBodyBellatrix.Attestations { + atts[i] = &Attestation{Attestation: b.BlindedBeaconBlockBodyBellatrix.Attestations[i]} + } + atsl := make([]*AttesterSlashing, len(b.BlindedBeaconBlockBodyBellatrix.AttesterSlashings)) + for i := range b.BlindedBeaconBlockBodyBellatrix.AttesterSlashings { + atsl[i] = &AttesterSlashing{AttesterSlashing: b.BlindedBeaconBlockBodyBellatrix.AttesterSlashings[i]} + } + pros := make([]*ProposerSlashing, len(b.BlindedBeaconBlockBodyBellatrix.ProposerSlashings)) + for i := range b.BlindedBeaconBlockBodyBellatrix.ProposerSlashings { + pros[i] = &ProposerSlashing{ProposerSlashing: b.BlindedBeaconBlockBodyBellatrix.ProposerSlashings[i]} + } return json.Marshal(struct { RandaoReveal hexutil.Bytes `json:"randao_reveal,omitempty"` Eth1Data *Eth1Data `json:"eth1_data,omitempty"` @@ -540,17 +555,18 @@ func (b *BlindedBeaconBlockBodyBellatrix) MarshalJSON() ([]byte, error) { Attestations []*Attestation `json:"attestations,omitempty"` Deposits []*Deposit `json:"deposits,omitempty"` VoluntaryExits []*SignedVoluntaryExit `json:"voluntary_exits,omitempty"` - SyncAggregates *SyncAggregate `json:"sync_aggregate,omitempty"` + SyncAggregate *SyncAggregate `json:"sync_aggregate,omitempty"` ExecutionPayloadHeader *ExecutionPayloadHeader `json:"execution_payload_header,omitempty"` }{ RandaoReveal: b.RandaoReveal, Eth1Data: &Eth1Data{b.BlindedBeaconBlockBodyBellatrix.Eth1Data}, Graffiti: b.BlindedBeaconBlockBodyBellatrix.Graffiti, - ProposerSlashings: []*ProposerSlashing{}, - AttesterSlashings: []*AttesterSlashing{}, - Attestations: []*Attestation{}, - Deposits: []*Deposit{}, - VoluntaryExits: []*SignedVoluntaryExit{}, + ProposerSlashings: pros, + AttesterSlashings: atsl, + Attestations: atts, + Deposits: deps, + VoluntaryExits: sve, + SyncAggregate: &SyncAggregate{b.BlindedBeaconBlockBodyBellatrix.SyncAggregate}, ExecutionPayloadHeader: &ExecutionPayloadHeader{ExecutionPayloadHeader: b.BlindedBeaconBlockBodyBellatrix.ExecutionPayloadHeader}, }) } diff --git a/api/client/builder/types_test.go b/api/client/builder/types_test.go index 98978dbea990..1b0bb21e6fa6 100644 --- a/api/client/builder/types_test.go +++ b/api/client/builder/types_test.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "math/big" + "os" "testing" "github.com/ethereum/go-ethereum/common/hexutil" @@ -378,13 +379,17 @@ func TestExecutionPayloadResponseToProto(t *testing.T) { require.DeepEqual(t, expected, p) } +func pbEth1Data(t *testing.T) *eth.Eth1Data { + return ð.Eth1Data{ + DepositRoot: make([]byte, 32), + DepositCount: 23, + BlockHash: make([]byte, 32), + } +} + func TestEth1DataMarshal(t *testing.T) { ed := &Eth1Data{ - Eth1Data: ð.Eth1Data{ - DepositRoot: make([]byte, 32), - DepositCount: 23, - BlockHash: make([]byte, 32), - }, + Eth1Data: pbEth1Data(t), } b, err := json.Marshal(ed) require.NoError(t, err) @@ -392,30 +397,36 @@ func TestEth1DataMarshal(t *testing.T) { require.Equal(t, expected, string(b)) } -func TestSyncAggregate_MarshalJSON(t *testing.T) { - sa := &SyncAggregate{ - ð.SyncAggregate{ - SyncCommitteeSignature: make([]byte, 48), - SyncCommitteeBits: bitfield.Bitvector512{0x01}, - }, +func pbSyncAggregate() *eth.SyncAggregate { + return ð.SyncAggregate{ + SyncCommitteeSignature: make([]byte, 48), + SyncCommitteeBits: bitfield.Bitvector512{0x01}, } +} + +func TestSyncAggregate_MarshalJSON(t *testing.T) { + sa := &SyncAggregate{pbSyncAggregate()} b, err := json.Marshal(sa) require.NoError(t, err) expected := `{"sync_committee_bits":"0x01","sync_committee_signature":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}` require.Equal(t, expected, string(b)) } +func pbDeposit(t *testing.T) *eth.Deposit { + return ð.Deposit{ + Proof: [][]byte{ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2")}, + Data: ð.Deposit_Data{ + PublicKey: ezDecode(t, "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a"), + WithdrawalCredentials: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Amount: 1, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + }, + } +} + func TestDeposit_MarshalJSON(t *testing.T) { d := &Deposit{ - Deposit: ð.Deposit{ - Proof: [][]byte{ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2")}, - Data: ð.Deposit_Data{ - PublicKey: ezDecode(t, "0x93247f2209abcacf57b75a51dafae777f9dd38bc7053d1af526f220a7489a6d3a2753e5f3e8b1cfe39b56f43611df74a"), - WithdrawalCredentials: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - Amount: 1, - Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), - }, - }, + Deposit: pbDeposit(t), } b, err := json.Marshal(d) require.NoError(t, err) @@ -423,15 +434,19 @@ func TestDeposit_MarshalJSON(t *testing.T) { require.Equal(t, expected, string(b)) } +func pbSignedVoluntaryExit(t *testing.T) *eth.SignedVoluntaryExit { + return ð.SignedVoluntaryExit{ + Exit: ð.VoluntaryExit{ + Epoch: 1, + ValidatorIndex: 1, + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + } +} + func TestVoluntaryExit(t *testing.T) { ve := &SignedVoluntaryExit{ - SignedVoluntaryExit: ð.SignedVoluntaryExit{ - Exit: ð.VoluntaryExit{ - Epoch: 1, - ValidatorIndex: 1, - }, - Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), - }, + SignedVoluntaryExit: pbSignedVoluntaryExit(t), } b, err := json.Marshal(ve) require.NoError(t, err) @@ -439,10 +454,58 @@ func TestVoluntaryExit(t *testing.T) { require.Equal(t, expected, string(b)) } +func pbAttestation(t *testing.T) *eth.Attestation { + return ð.Attestation{ + AggregationBits: bitfield.Bitlist{0x01}, + Data: ð.AttestationData{ + Slot: 1, + CommitteeIndex: 1, + BeaconBlockRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Source: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Target: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + }, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + } +} + func TestAttestationMarshal(t *testing.T) { a := &Attestation{ - Attestation: ð.Attestation{ - AggregationBits: bitfield.Bitlist{0x01}, + Attestation: pbAttestation(t), + } + b, err := json.Marshal(a) + require.NoError(t, err) + expected := `{"aggregation_bits":"0x01","data":{"slot":"1","index":"1","beacon_block_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","source":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"target":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}` + require.Equal(t, expected, string(b)) +} + +func pbAttesterSlashing(t *testing.T) *eth.AttesterSlashing { + return ð.AttesterSlashing{ + Attestation_1: ð.IndexedAttestation{ + AttestingIndices: []uint64{1}, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + Data: ð.AttestationData{ + Slot: 1, + CommitteeIndex: 1, + BeaconBlockRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Source: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + Target: ð.Checkpoint{ + Epoch: 1, + Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + }, + }, + }, + Attestation_2: ð.IndexedAttestation{ + AttestingIndices: []uint64{1}, + Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), Data: ð.AttestationData{ Slot: 1, CommitteeIndex: 1, @@ -456,62 +519,22 @@ func TestAttestationMarshal(t *testing.T) { Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), }, }, - Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), }, } - b, err := json.Marshal(a) - require.NoError(t, err) - expected := `{"aggregation_bits":"0x01","data":{"slot":"1","index":"1","beacon_block_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","source":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"target":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}` - require.Equal(t, expected, string(b)) } func TestAttesterSlashing_MarshalJSON(t *testing.T) { as := &AttesterSlashing{ - AttesterSlashing: ð.AttesterSlashing{ - Attestation_1: ð.IndexedAttestation{ - AttestingIndices: []uint64{1}, - Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), - Data: ð.AttestationData{ - Slot: 1, - CommitteeIndex: 1, - BeaconBlockRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - Source: ð.Checkpoint{ - Epoch: 1, - Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - }, - Target: ð.Checkpoint{ - Epoch: 1, - Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - }, - }, - }, - Attestation_2: ð.IndexedAttestation{ - AttestingIndices: []uint64{1}, - Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), - Data: ð.AttestationData{ - Slot: 1, - CommitteeIndex: 1, - BeaconBlockRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - Source: ð.Checkpoint{ - Epoch: 1, - Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - }, - Target: ð.Checkpoint{ - Epoch: 1, - Root: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - }, - }, - }, - }, + AttesterSlashing: pbAttesterSlashing(t), } b, err := json.Marshal(as) require.NoError(t, err) - expected := `{"attestation_1":{"attesting_indices":["1"],"Data":{"slot":"1","index":"1","beacon_block_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","source":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"target":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"},"attestation_2":{"attesting_indices":["1"],"Data":{"slot":"1","index":"1","beacon_block_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","source":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"target":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}}` + expected := `{"attestation_1":{"attesting_indices":["1"],"data":{"slot":"1","index":"1","beacon_block_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","source":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"target":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"},"attestation_2":{"attesting_indices":["1"],"data":{"slot":"1","index":"1","beacon_block_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","source":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"target":{"epoch":"1","root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"}},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}}` require.Equal(t, expected, string(b)) } -func TestProposerSlashings(t *testing.T) { - ps := &ProposerSlashing{ð.ProposerSlashing{ +func pbProposerSlashing(t *testing.T) *eth.ProposerSlashing { + return ð.ProposerSlashing{ Header_1: ð.SignedBeaconBlockHeader{ Header: ð.BeaconBlockHeader{ Slot: 1, @@ -532,32 +555,40 @@ func TestProposerSlashings(t *testing.T) { }, Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), }, - }} + } +} + +func TestProposerSlashings(t *testing.T) { + ps := &ProposerSlashing{ProposerSlashing: pbProposerSlashing(t)} b, err := json.Marshal(ps) require.NoError(t, err) expected := `{"signed_header_1":{"message":{"slot":"1","proposer_index":"1","parent_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","state_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","body_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"},"signed_header_2":{"message":{"slot":"1","proposer_index":"1","parent_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","state_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","body_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"},"signature":"0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"}}` require.Equal(t, expected, string(b)) } -func TestExecutionPayloadHeader_MarshalJSON(t *testing.T) { +func pbExecutionPayloadHeader(t *testing.T) *eth.ExecutionPayloadHeader { bfpg := stringToUint256("452312848583266388373324160190187140051835877600158453279131187530910662656") + return ð.ExecutionPayloadHeader{ + ParentHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + FeeRecipient: ezDecode(t, "0xabcf8e0d4e9587369b2301d0790347320302cc09"), + StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + ReceiptsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + LogsBloom: ezDecode(t, "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + PrevRandao: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BlockNumber: 1, + GasLimit: 1, + GasUsed: 1, + Timestamp: 1, + ExtraData: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + BaseFeePerGas: bfpg.SSZBytes(), + BlockHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + TransactionsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + } +} + +func TestExecutionPayloadHeader_MarshalJSON(t *testing.T) { h := &ExecutionPayloadHeader{ - ExecutionPayloadHeader: ð.ExecutionPayloadHeader{ - ParentHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - FeeRecipient: ezDecode(t, "0xabcf8e0d4e9587369b2301d0790347320302cc09"), - StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - ReceiptsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - LogsBloom: ezDecode(t, "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - PrevRandao: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - BlockNumber: 1, - GasLimit: 1, - GasUsed: 1, - Timestamp: 1, - ExtraData: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - BaseFeePerGas: bfpg.SSZBytes(), - BlockHash: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - TransactionsRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), - }, + ExecutionPayloadHeader: pbExecutionPayloadHeader(t), } b, err := json.Marshal(h) require.NoError(t, err) @@ -631,3 +662,32 @@ func TestUint256Unmarshal(t *testing.T) { expected := `{"big_number":"452312848583266388373324160190187140051835877600158453279131187530910662656"}` require.Equal(t, expected, string(m)) } + +func TestMarshalBlindedBeaconBlockBodyBellatrix(t *testing.T) { + expected, err := os.ReadFile("testdata/blinded-block.json") + require.NoError(t, err) + b := &BlindedBeaconBlockBellatrix{BlindedBeaconBlockBellatrix: ð.BlindedBeaconBlockBellatrix{ + Slot: 1, + ProposerIndex: 1, + ParentRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), + Body: ð.BlindedBeaconBlockBodyBellatrix{ + RandaoReveal: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), + Eth1Data: pbEth1Data(t), + Graffiti: ezDecode(t, "0xdeadbeefc0ffee"), + ProposerSlashings: []*eth.ProposerSlashing{pbProposerSlashing(t)}, + AttesterSlashings: []*eth.AttesterSlashing{pbAttesterSlashing(t)}, + Attestations: []*eth.Attestation{pbAttestation(t)}, + Deposits: []*eth.Deposit{pbDeposit(t)}, + VoluntaryExits: []*eth.SignedVoluntaryExit{pbSignedVoluntaryExit(t)}, + SyncAggregate: pbSyncAggregate(), + ExecutionPayloadHeader: pbExecutionPayloadHeader(t), + }, + }} + m, err := json.Marshal(b) + require.NoError(t, err) + // string error output is easier to deal with + // -1 end slice index on expected is to get rid of trailing newline + // if you update this fixture and this test breaks, you probably removed the trailing newline + require.Equal(t, string(expected[0:len(expected)-1]), string(m)) +} From 6f71ab16e678a0c2121983f8718bd6c8a0e18042 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 15:26:50 -0500 Subject: [PATCH 11/21] appease deepsource --- api/client/builder/types_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/client/builder/types_test.go b/api/client/builder/types_test.go index 1b0bb21e6fa6..050f6d320fd2 100644 --- a/api/client/builder/types_test.go +++ b/api/client/builder/types_test.go @@ -379,7 +379,7 @@ func TestExecutionPayloadResponseToProto(t *testing.T) { require.DeepEqual(t, expected, p) } -func pbEth1Data(t *testing.T) *eth.Eth1Data { +func pbEth1Data() *eth.Eth1Data { return ð.Eth1Data{ DepositRoot: make([]byte, 32), DepositCount: 23, @@ -389,7 +389,7 @@ func pbEth1Data(t *testing.T) *eth.Eth1Data { func TestEth1DataMarshal(t *testing.T) { ed := &Eth1Data{ - Eth1Data: pbEth1Data(t), + Eth1Data: pbEth1Data(), } b, err := json.Marshal(ed) require.NoError(t, err) @@ -673,7 +673,7 @@ func TestMarshalBlindedBeaconBlockBodyBellatrix(t *testing.T) { StateRoot: ezDecode(t, "0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"), Body: ð.BlindedBeaconBlockBodyBellatrix{ RandaoReveal: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), - Eth1Data: pbEth1Data(t), + Eth1Data: pbEth1Data(), Graffiti: ezDecode(t, "0xdeadbeefc0ffee"), ProposerSlashings: []*eth.ProposerSlashing{pbProposerSlashing(t)}, AttesterSlashings: []*eth.AttesterSlashing{pbAttesterSlashing(t)}, From 22a84ac1c856ada3e7e198608759f04966f211ee Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 16:22:04 -0500 Subject: [PATCH 12/21] middleware to log requests --- api/client/builder/client.go | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/api/client/builder/client.go b/api/client/builder/client.go index 27e1f4240820..a482d38a765d 100644 --- a/api/client/builder/client.go +++ b/api/client/builder/client.go @@ -39,10 +39,46 @@ func WithTimeout(timeout time.Duration) ClientOpt { } } +type observer interface { + observe(r http.Request) error +} + +func WithObserver(m observer) ClientOpt { + return func(c *Client) { + c.mw = append(c.mw, m) + } +} + +type requestLogger struct{} + +func (l *requestLogger) observe(r http.Request) (e error) { + b := bytes.NewBuffer(nil) + t := io.TeeReader(r.Body, b) + defer func() { + if r.Body != nil { + e = r.Body.Close() + } + }() + body, err := io.ReadAll(t) + if err != nil { + return err + } + r.Body = io.NopCloser(b) + log.WithFields(log.Fields{ + "body-base64": string(body), + "url": r.URL.String(), + }).Info("builder http request") + + return nil +} + +var _ observer = &requestLogger{} + // Client provides a collection of helper methods for calling Builder API endpoints. type Client struct { hc *http.Client baseURL *url.URL + mw []observer } // NewClient constructs a new client with the provided options (ex WithTimeout). From 9d22feb90ccc6e9548387d3a080949e405685a9a Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 16:27:58 -0500 Subject: [PATCH 13/21] big int round trip test --- api/client/builder/types_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/api/client/builder/types_test.go b/api/client/builder/types_test.go index 050f6d320fd2..c5c2fb074b0f 100644 --- a/api/client/builder/types_test.go +++ b/api/client/builder/types_test.go @@ -1,6 +1,7 @@ package builder import ( + "bytes" "encoding/json" "fmt" "math/big" @@ -691,3 +692,12 @@ func TestMarshalBlindedBeaconBlockBodyBellatrix(t *testing.T) { // if you update this fixture and this test breaks, you probably removed the trailing newline require.Equal(t, string(expected[0:len(expected)-1]), string(m)) } + +func TestRoundTripUint256(t *testing.T) { + vs := "452312848583266388373324160190187140051835877600158453279131187530910662656" + u := stringToUint256(vs) + sb := u.SSZBytes() + uu := sszBytesToUint256(sb) + require.Equal(t, true, bytes.Equal(u.SSZBytes(), uu.SSZBytes())) + require.Equal(t, vs, uu.String()) +} From 58c2332f02811b0f7307fd9d5635d939cc9b1fa3 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 16:40:54 -0500 Subject: [PATCH 14/21] very superficial test to make deepsource happy --- api/client/builder/client_test.go | 21 +++++++++++++++++++++ api/client/builder/types_test.go | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/api/client/builder/client_test.go b/api/client/builder/client_test.go index 0fe489de5f42..767878793337 100644 --- a/api/client/builder/client_test.go +++ b/api/client/builder/client_test.go @@ -321,3 +321,24 @@ func testSignedBlindedBeaconBlockBellatrix(t *testing.T) *eth.SignedBlindedBeaco Signature: ezDecode(t, "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505"), } } + +func TestRequestLogger(t *testing.T) { + wo := WithObserver(&requestLogger{}) + c, err := NewClient("localhost:3500", wo) + require.NoError(t, err) + + ctx := context.Background() + hc := &http.Client{ + Transport: roundtrip(func(r *http.Request) (*http.Response, error) { + require.Equal(t, getStatus, r.URL.Path) + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(bytes.NewBufferString(testExampleExecutionPayload)), + Request: r.Clone(ctx), + }, nil + }), + } + c.hc = hc + err = c.Status(ctx) + require.NoError(t, err) +} diff --git a/api/client/builder/types_test.go b/api/client/builder/types_test.go index c5c2fb074b0f..244dc63be28f 100644 --- a/api/client/builder/types_test.go +++ b/api/client/builder/types_test.go @@ -700,4 +700,4 @@ func TestRoundTripUint256(t *testing.T) { uu := sszBytesToUint256(sb) require.Equal(t, true, bytes.Equal(u.SSZBytes(), uu.SSZBytes())) require.Equal(t, vs, uu.String()) -} +} \ No newline at end of file From 2dd4950d7a4564b741f32e5df563d813eceb8eb0 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 16:53:43 -0500 Subject: [PATCH 15/21] round trip test between proto payloads --- api/client/builder/types_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/api/client/builder/types_test.go b/api/client/builder/types_test.go index 244dc63be28f..c94df5de92b6 100644 --- a/api/client/builder/types_test.go +++ b/api/client/builder/types_test.go @@ -700,4 +700,17 @@ func TestRoundTripUint256(t *testing.T) { uu := sszBytesToUint256(sb) require.Equal(t, true, bytes.Equal(u.SSZBytes(), uu.SSZBytes())) require.Equal(t, vs, uu.String()) +} + +func TestRoundTripProtoUint256(t *testing.T) { + h := pbExecutionPayloadHeader(t) + h.BaseFeePerGas = []byte{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31} + hm := &ExecutionPayloadHeader{ExecutionPayloadHeader: h} + m, err := json.Marshal(hm) + require.NoError(t, err) + hu := &ExecutionPayloadHeader{} + require.NoError(t, json.Unmarshal(m, hu)) + hp, err := hu.ToProto() + require.NoError(t, err) + require.DeepEqual(t, h.BaseFeePerGas, hp.BaseFeePerGas) } \ No newline at end of file From da1236fadd09228733b518fae162363af26f2684 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 17:07:23 -0500 Subject: [PATCH 16/21] round trip starting from marshaled struct --- api/client/builder/testdata/execution-payload.json | 1 + api/client/builder/types.go | 13 +++++++++++++ api/client/builder/types_test.go | 11 +++++++++++ 3 files changed, 25 insertions(+) create mode 100644 api/client/builder/testdata/execution-payload.json diff --git a/api/client/builder/testdata/execution-payload.json b/api/client/builder/testdata/execution-payload.json new file mode 100644 index 000000000000..ce8ef1655a67 --- /dev/null +++ b/api/client/builder/testdata/execution-payload.json @@ -0,0 +1 @@ +{"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":"14074904626401341155369551180448584754667373453244490859944217516317499064576","block_hash":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2","transactions_root":"0xcf8e0d4e9587369b2301d0790347320302cc0943d5a1884560367e8208d920f2"} diff --git a/api/client/builder/types.go b/api/client/builder/types.go index 4d065335393a..c39d1259e442 100644 --- a/api/client/builder/types.go +++ b/api/client/builder/types.go @@ -212,6 +212,19 @@ func (h *ExecutionPayloadHeader) MarshalJSON() ([]byte, error) { }) } +func (h *ExecutionPayloadHeader) UnmarshalJSON(b []byte) (error) { + type UnmarshalCaller ExecutionPayloadHeader + uc := &UnmarshalCaller{} + if err := json.Unmarshal(b, uc); err != nil { + return err + } + ep := ExecutionPayloadHeader(*uc) + *h = ep + var err error + h.ExecutionPayloadHeader, err = h.ToProto() + return err +} + type ExecPayloadResponse struct { Version string `json:"version,omitempty"` Data ExecutionPayload `json:"data,omitempty"` diff --git a/api/client/builder/types_test.go b/api/client/builder/types_test.go index c94df5de92b6..4116fede5022 100644 --- a/api/client/builder/types_test.go +++ b/api/client/builder/types_test.go @@ -709,8 +709,19 @@ func TestRoundTripProtoUint256(t *testing.T) { m, err := json.Marshal(hm) require.NoError(t, err) hu := &ExecutionPayloadHeader{} + require.Equal(t, "", string(m)) require.NoError(t, json.Unmarshal(m, hu)) hp, err := hu.ToProto() require.NoError(t, err) require.DeepEqual(t, h.BaseFeePerGas, hp.BaseFeePerGas) +} + +func TestExecutionPayloadHeaderRoundtrip(t *testing.T) { + expected, err := os.ReadFile("testdata/execution-payload.json") + require.NoError(t, err) + hu := &ExecutionPayloadHeader{} + require.NoError(t, json.Unmarshal(expected, hu)) + m, err := json.Marshal(hu) + require.NoError(t, err) + require.DeepEqual(t, string(expected[0:len(expected)-1]), string(m)) } \ No newline at end of file From fdb30d52daab302fb00a1b2dd8b71231629a0a5e Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 17:25:08 -0500 Subject: [PATCH 17/21] deepsource... for you, the moon --- api/client/builder/client.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/api/client/builder/client.go b/api/client/builder/client.go index a482d38a765d..a0e6b7a411bf 100644 --- a/api/client/builder/client.go +++ b/api/client/builder/client.go @@ -40,18 +40,18 @@ func WithTimeout(timeout time.Duration) ClientOpt { } type observer interface { - observe(r http.Request) error + observe(r *http.Request) error } func WithObserver(m observer) ClientOpt { return func(c *Client) { - c.mw = append(c.mw, m) + c.obvs = append(c.obvs, m) } } type requestLogger struct{} -func (l *requestLogger) observe(r http.Request) (e error) { +func (l *requestLogger) observe(r *http.Request) (e error) { b := bytes.NewBuffer(nil) t := io.TeeReader(r.Body, b) defer func() { @@ -78,7 +78,7 @@ var _ observer = &requestLogger{} type Client struct { hc *http.Client baseURL *url.URL - mw []observer + obvs []observer } // NewClient constructs a new client with the provided options (ex WithTimeout). @@ -131,6 +131,11 @@ func (c *Client) do(ctx context.Context, method string, path string, body io.Rea for _, o := range opts { o(req) } + for _, o := range c.obvs { + if err := o.observe(req); err != nil { + return nil, err + } + } r, err := c.hc.Do(req) if err != nil { return nil, err From af0991a73e004e97aadeb13f5fa5d447ca148c25 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 17:31:50 -0500 Subject: [PATCH 18/21] remove unused receiver --- api/client/builder/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client/builder/client.go b/api/client/builder/client.go index a0e6b7a411bf..e8aec28b6f94 100644 --- a/api/client/builder/client.go +++ b/api/client/builder/client.go @@ -51,7 +51,7 @@ func WithObserver(m observer) ClientOpt { type requestLogger struct{} -func (l *requestLogger) observe(r *http.Request) (e error) { +func (*requestLogger) observe(r *http.Request) (e error) { b := bytes.NewBuffer(nil) t := io.TeeReader(r.Body, b) defer func() { From ecda261122e93718ff2713718eeb0d1c1bf85c12 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Fri, 20 May 2022 17:39:30 -0500 Subject: [PATCH 19/21] gofmt --- api/client/builder/types.go | 2 +- api/client/builder/types_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/api/client/builder/types.go b/api/client/builder/types.go index c39d1259e442..a54b797eca9d 100644 --- a/api/client/builder/types.go +++ b/api/client/builder/types.go @@ -212,7 +212,7 @@ func (h *ExecutionPayloadHeader) MarshalJSON() ([]byte, error) { }) } -func (h *ExecutionPayloadHeader) UnmarshalJSON(b []byte) (error) { +func (h *ExecutionPayloadHeader) UnmarshalJSON(b []byte) error { type UnmarshalCaller ExecutionPayloadHeader uc := &UnmarshalCaller{} if err := json.Unmarshal(b, uc); err != nil { diff --git a/api/client/builder/types_test.go b/api/client/builder/types_test.go index 4116fede5022..5393c02fec66 100644 --- a/api/client/builder/types_test.go +++ b/api/client/builder/types_test.go @@ -704,7 +704,7 @@ func TestRoundTripUint256(t *testing.T) { func TestRoundTripProtoUint256(t *testing.T) { h := pbExecutionPayloadHeader(t) - h.BaseFeePerGas = []byte{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31} + h.BaseFeePerGas = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31} hm := &ExecutionPayloadHeader{ExecutionPayloadHeader: h} m, err := json.Marshal(hm) require.NoError(t, err) @@ -724,4 +724,4 @@ func TestExecutionPayloadHeaderRoundtrip(t *testing.T) { m, err := json.Marshal(hu) require.NoError(t, err) require.DeepEqual(t, string(expected[0:len(expected)-1]), string(m)) -} \ No newline at end of file +} From f5cff7cb34a866b16b58bfced02acba5d211d982 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Mon, 23 May 2022 11:13:24 -0500 Subject: [PATCH 20/21] remove test destroying line added while debugging --- api/client/builder/types_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/api/client/builder/types_test.go b/api/client/builder/types_test.go index 5393c02fec66..a75f5e5c5af5 100644 --- a/api/client/builder/types_test.go +++ b/api/client/builder/types_test.go @@ -709,7 +709,6 @@ func TestRoundTripProtoUint256(t *testing.T) { m, err := json.Marshal(hm) require.NoError(t, err) hu := &ExecutionPayloadHeader{} - require.Equal(t, "", string(m)) require.NoError(t, json.Unmarshal(m, hu)) hp, err := hu.ToProto() require.NoError(t, err) From acf1929d64d4333d1ed1212fbb04efed4ad25b51 Mon Sep 17 00:00:00 2001 From: Kasey Kirkham Date: Mon, 23 May 2022 11:25:20 -0500 Subject: [PATCH 21/21] handle nil body in logging middleware --- api/client/builder/client.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/api/client/builder/client.go b/api/client/builder/client.go index e8aec28b6f94..6d64ab7a5496 100644 --- a/api/client/builder/client.go +++ b/api/client/builder/client.go @@ -53,6 +53,13 @@ type requestLogger struct{} func (*requestLogger) observe(r *http.Request) (e error) { b := bytes.NewBuffer(nil) + if r.Body == nil { + log.WithFields(log.Fields{ + "body-base64": "(nil value)", + "url": r.URL.String(), + }).Info("builder http request") + return nil + } t := io.TeeReader(r.Body, b) defer func() { if r.Body != nil {