Skip to content

Commit

Permalink
Add unblind block.
Browse files Browse the repository at this point in the history
  • Loading branch information
mcdee committed Mar 15, 2024
1 parent 2dcbf82 commit 2b77918
Show file tree
Hide file tree
Showing 11 changed files with 438 additions and 15 deletions.
19 changes: 19 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright © 2024 Attestant Limited.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package client

import "errors"

// ErrInvalidOptions is returned when a request is made with invalid options.
var ErrInvalidOptions = errors.New("invalid options")
39 changes: 39 additions & 0 deletions services/blockunblinder/mock/erroring.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright © 2024 Attestant Limited.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mock

import (
"context"
"errors"

"github.com/attestantio/go-eth2-client/api"
)

// ErroringService is a mock block unblinder.
type ErroringService struct{}

// NewErroring creates a new mock block unblinder.
func NewErroring() *ErroringService {
return &ErroringService{}
}

// UnblindBlock unblinds the given block.
func (s *ErroringService) UnblindBlock(_ context.Context,
_ *api.VersionedSignedBlindedBeaconBlock,
) (
*api.VersionedSignedProposal,
error,
) {
return nil, errors.New("error")
}
38 changes: 38 additions & 0 deletions services/blockunblinder/mock/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright © 2024 Attestant Limited.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mock

import (
"context"

"github.com/attestantio/go-eth2-client/api"
)

// Service is a mock block auctioneer.
type Service struct{}

// New creates a new mock block auctioneer.
func New() *Service {
return &Service{}
}

// UnblindBlock unblinds the given block.
func (s *Service) UnblindBlock(_ context.Context,
_ *api.VersionedSignedBlindedBeaconBlock,
) (
*api.VersionedSignedProposal,
error,
) {
return &api.VersionedSignedProposal{}, nil
}
10 changes: 3 additions & 7 deletions services/blockunblinder/service.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2022 Attestant Limited.
// Copyright © 2022, 2024 Attestant Limited.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
Expand All @@ -17,19 +17,15 @@ import (
"context"

"github.com/attestantio/go-eth2-client/api"
"github.com/attestantio/go-eth2-client/spec"
)

// Service defines the block unblinder service.
type Service interface{}

// BlockUnblinder is the interface for unblinding blocks.
type BlockUnblinder interface {
type Service interface {
// UnblindBlock unblinds the given block.
UnblindBlock(ctx context.Context,
block *api.VersionedSignedBlindedBeaconBlock,
) (
*spec.VersionedSignedBeaconBlock,
*api.VersionedSignedProposal,
error,
)
}
10 changes: 8 additions & 2 deletions services/daemon/rest/builderbid.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2022, 204 Attestant Limited.
// Copyright © 2022, 2024 Attestant Limited.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
Expand All @@ -15,11 +15,13 @@ package rest

import (
"encoding/hex"
"errors"
"fmt"
"net/http"
"strconv"
"strings"

relay "github.com/attestantio/go-block-relay"
"github.com/attestantio/go-eth2-client/spec/phase0"
"github.com/gorilla/mux"
)
Expand Down Expand Up @@ -70,9 +72,13 @@ func (s *Service) getBuilderBid(w http.ResponseWriter, r *http.Request) {

bid, err := s.builderBidProvider.BuilderBid(r.Context(), slot, parentHash, pubkey)
if err != nil {
code := http.StatusInternalServerError
if errors.Is(err, relay.ErrInvalidOptions) {
code = http.StatusBadRequest
}
s.log.Error().Err(err).Msg("Failed to obtain bid")
s.sendResponse(w, http.StatusInternalServerError, &APIResponse{
Code: http.StatusInternalServerError,
Code: code,
Message: "Failed to obtain bid",
})
monitorRequestHandled("builder bid", "failure")
Expand Down
14 changes: 13 additions & 1 deletion services/daemon/rest/parameters.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2022 Attestant Limited.
// Copyright © 2022, 2024 Attestant Limited.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
Expand All @@ -17,6 +17,7 @@ import (
"errors"

"github.com/attestantio/go-block-relay/services/blockauctioneer"
"github.com/attestantio/go-block-relay/services/blockunblinder"
"github.com/attestantio/go-block-relay/services/builderbidprovider"
"github.com/attestantio/go-block-relay/services/metrics"
nullmetrics "github.com/attestantio/go-block-relay/services/metrics/null"
Expand All @@ -32,6 +33,7 @@ type parameters struct {
validatorRegistrar validatorregistrar.Service
blockAuctioneer blockauctioneer.Service
builderBidProvider builderbidprovider.Service
blockUnblinder blockunblinder.Service
}

// Parameter is the interface for service parameters.
Expand Down Expand Up @@ -94,6 +96,13 @@ func WithBlockAuctioneer(blockAuctioneer blockauctioneer.Service) Parameter {
})
}

// WithBlockUnblinder sets the block unblinder.
func WithBlockUnblinder(blockUnblinder blockunblinder.Service) Parameter {
return parameterFunc(func(p *parameters) {
p.blockUnblinder = blockUnblinder
})
}

// parseAndCheckParameters parses and checks parameters to ensure that mandatory parameters are present and correct.
func parseAndCheckParameters(params ...Parameter) (*parameters, error) {
parameters := parameters{
Expand Down Expand Up @@ -122,6 +131,9 @@ func parseAndCheckParameters(params ...Parameter) (*parameters, error) {
if parameters.blockAuctioneer == nil {
return nil, errors.New("no block auctioneer specified")
}
if parameters.blockUnblinder == nil {
return nil, errors.New("no block unblinder specified")
}
if parameters.builderBidProvider == nil {
return nil, errors.New("no builder bid provider specified")
}
Expand Down
13 changes: 12 additions & 1 deletion services/daemon/rest/service.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2022 Attestant Limited.
// Copyright © 2022, 2024 Attestant Limited.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
Expand All @@ -22,6 +22,7 @@ import (
"time"

"github.com/attestantio/go-block-relay/loggers"
"github.com/attestantio/go-block-relay/services/blockunblinder"
"github.com/attestantio/go-block-relay/services/builderbidprovider"
"github.com/attestantio/go-block-relay/services/validatorregistrar"
"github.com/gin-gonic/gin"
Expand All @@ -37,6 +38,7 @@ type Service struct {
srv *http.Server
validatorRegistrar validatorregistrar.Service
builderBidProvider builderbidprovider.Service
blockUnblinder blockunblinder.Service
}

// New creates a new REST daemon service.
Expand All @@ -60,6 +62,7 @@ func New(ctx context.Context, params ...Parameter) (*Service, error) {
log: log,
validatorRegistrar: parameters.validatorRegistrar,
builderBidProvider: parameters.builderBidProvider,
blockUnblinder: parameters.blockUnblinder,
}

if err := s.startServer(ctx, parameters.serverName, parameters.listenAddress); err != nil {
Expand Down Expand Up @@ -88,6 +91,8 @@ func (s *Service) startServer(ctx context.Context,
router.HandleFunc("/eth/v1/builder/validators", s.postValidatorRegistrations).Methods("POST")
router.HandleFunc("/eth/v1/builder/header/{slot}/{parenthash}/{pubkey}", s.getBuilderBid).Methods("GET")
router.HandleFunc("/eth/v1/builder/status", s.getStatus).Methods("GET")
router.HandleFunc("/eth/v1/builder/blinded_blocks", s.postUnblindBlock).Methods("POST")
router.PathPrefix("/").Handler(s)

s.srv = &http.Server{
Addr: listenAddress,
Expand Down Expand Up @@ -180,3 +185,9 @@ func (s *Service) sigloop(ctx context.Context) {
}
}
}

func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
s.log.Debug().Str("method", r.Method).Stringer("url", r.URL).Msg("Unhandled request")

w.WriteHeader(http.StatusNotFound)
}
24 changes: 23 additions & 1 deletion services/daemon/rest/service_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2022 Attestant Limited.
// Copyright © 2022, 2024 Attestant Limited.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
Expand All @@ -19,6 +19,7 @@ import (
"time"

mockauctioneer "github.com/attestantio/go-block-relay/services/blockauctioneer/mock"
mockblockunblinder "github.com/attestantio/go-block-relay/services/blockunblinder/mock"
mockbuilderbidprovider "github.com/attestantio/go-block-relay/services/builderbidprovider/mock"
restdaemon "github.com/attestantio/go-block-relay/services/daemon/rest"
nullmetrics "github.com/attestantio/go-block-relay/services/metrics/null"
Expand All @@ -33,6 +34,7 @@ func TestService(t *testing.T) {
registrar := mockregistrar.New()
auctioneer := mockauctioneer.New()
monitor := nullmetrics.New()
unblinder := mockblockunblinder.New()
builderBidProvider := mockbuilderbidprovider.New()

tests := []struct {
Expand All @@ -48,6 +50,7 @@ func TestService(t *testing.T) {
restdaemon.WithListenAddress(":14734"),
restdaemon.WithValidatorRegistrar(registrar),
restdaemon.WithBlockAuctioneer(auctioneer),
restdaemon.WithBlockUnblinder(unblinder),
restdaemon.WithBuilderBidProvider(builderBidProvider),
},
err: "problem with parameters: no monitor specified",
Expand All @@ -59,6 +62,7 @@ func TestService(t *testing.T) {
restdaemon.WithMonitor(monitor),
restdaemon.WithValidatorRegistrar(registrar),
restdaemon.WithBlockAuctioneer(auctioneer),
restdaemon.WithBlockUnblinder(unblinder),
restdaemon.WithBuilderBidProvider(builderBidProvider),
},
err: "problem with parameters: no listen address specified",
Expand All @@ -70,6 +74,7 @@ func TestService(t *testing.T) {
restdaemon.WithMonitor(monitor),
restdaemon.WithListenAddress(":14734"),
restdaemon.WithBlockAuctioneer(auctioneer),
restdaemon.WithBlockUnblinder(unblinder),
restdaemon.WithBuilderBidProvider(builderBidProvider),
},
err: "problem with parameters: no validator registrar specified",
Expand All @@ -81,6 +86,7 @@ func TestService(t *testing.T) {
restdaemon.WithMonitor(monitor),
restdaemon.WithListenAddress(":14734"),
restdaemon.WithValidatorRegistrar(registrar),
restdaemon.WithBlockUnblinder(unblinder),
restdaemon.WithBuilderBidProvider(builderBidProvider),
},
err: "problem with parameters: no block auctioneer specified",
Expand All @@ -93,9 +99,22 @@ func TestService(t *testing.T) {
restdaemon.WithListenAddress(":14734"),
restdaemon.WithValidatorRegistrar(registrar),
restdaemon.WithBlockAuctioneer(auctioneer),
restdaemon.WithBlockUnblinder(unblinder),
},
err: "problem with parameters: no builder bid provider specified",
},
{
name: "BlockUnblindedMissing",
params: []restdaemon.Parameter{
restdaemon.WithLogLevel(zerolog.Disabled),
restdaemon.WithMonitor(monitor),
restdaemon.WithListenAddress(":14734"),
restdaemon.WithValidatorRegistrar(registrar),
restdaemon.WithBlockAuctioneer(auctioneer),
restdaemon.WithBuilderBidProvider(builderBidProvider),
},
err: "problem with parameters: no block unblinder specified",
},
{
name: "Good",
params: []restdaemon.Parameter{
Expand All @@ -104,6 +123,7 @@ func TestService(t *testing.T) {
restdaemon.WithListenAddress(":14734"),
restdaemon.WithValidatorRegistrar(registrar),
restdaemon.WithBlockAuctioneer(auctioneer),
restdaemon.WithBlockUnblinder(unblinder),
restdaemon.WithBuilderBidProvider(builderBidProvider),
},
},
Expand All @@ -125,6 +145,7 @@ func TestShutdown(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
registrar := mockregistrar.New()
auctioneer := mockauctioneer.New()
unblinder := mockblockunblinder.New()
monitor := nullmetrics.New()
builderBidProvider := mockbuilderbidprovider.New()

Expand All @@ -134,6 +155,7 @@ func TestShutdown(t *testing.T) {
restdaemon.WithListenAddress(":14734"),
restdaemon.WithValidatorRegistrar(registrar),
restdaemon.WithBlockAuctioneer(auctioneer),
restdaemon.WithBlockUnblinder(unblinder),
restdaemon.WithBuilderBidProvider(builderBidProvider),
)
require.NoError(t, err)
Expand Down
Loading

0 comments on commit 2b77918

Please sign in to comment.