Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add runtime flag to disable solo validator access #39

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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 12 additions & 17 deletions executionlayer/execution-layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,32 +433,27 @@ func (e *ExecutionLayer) ecEventsConnect(opts *bind.CallOpts) error {
case err := <-(*logSubscription).Err():
(*newHeadSubscription).Unsubscribe()
e.handleSubscriptionError(err, &logSubscription, &newHeadSubscription)
break
case err := <-(*newHeadSubscription).Err():
(*logSubscription).Unsubscribe()
e.handleSubscriptionError(err, &logSubscription, &newHeadSubscription)
break
case event, ok := <-e.events:
noMoreEvents = !ok
if noMoreEvents {
break
if !noMoreEvents {
e.handleEvent(event)
}
e.handleEvent(event)
case newHeader, ok := <-e.newHeaders:
noMoreHeaders = !ok
if noMoreHeaders {
break
if !noMoreHeaders {
// Just advance highest block
e.m.Counter("block_header_received").Inc()
e.Logger.Debug("New block received",
zap.Int64("new height", newHeader.Number.Int64()),
zap.Int64("old height", e.cache.getHighestBlock().Int64()))
e.cache.setHighestBlock(newHeader.Number)

// Continue here to check for new events
continue
}

// Just advance highest block
e.m.Counter("block_header_received").Inc()
e.Logger.Debug("New block received",
zap.Int64("new height", newHeader.Number.Int64()),
zap.Int64("old height", e.cache.getHighestBlock().Int64()))
e.cache.setHighestBlock(newHeader.Number)

// Continue here to check for new events
continue
}

// If we didn't process any events in the select and the channels are closed,
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.20

require (
github.com/Rocket-Pool-Rescue-Node/credentials v0.0.0-20230909140515-dbe2112cbe11
github.com/Rocket-Rescue-Node/guarded-beacon-proxy v0.1.0
github.com/Rocket-Rescue-Node/guarded-beacon-proxy v0.1.1
github.com/allegro/bigcache/v3 v3.1.0
github.com/attestantio/go-eth2-client v0.18.3
github.com/ethereum/go-ethereum v1.12.2
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ github.com/Rocket-Pool-Rescue-Node/credentials v0.0.0-20230909140515-dbe2112cbe1
github.com/Rocket-Pool-Rescue-Node/credentials v0.0.0-20230909140515-dbe2112cbe11/go.mod h1:a8WDDCTOY1g5tQG9myB5UMEg+4tCLAtVm++Qm5Ki6iA=
github.com/Rocket-Rescue-Node/guarded-beacon-proxy v0.1.0 h1:GeVdL1FdnpO4RuyY+QqfiRmfwkeSzoTe8IuLuLTS0u8=
github.com/Rocket-Rescue-Node/guarded-beacon-proxy v0.1.0/go.mod h1:p4CMEZjb+V4hI6vaAoOTplAi6pZLHCtnw163NdMztgo=
github.com/Rocket-Rescue-Node/guarded-beacon-proxy v0.1.1 h1:MyGF9V64MATdqFI2nri8u1PWgGPOlCxqkxfiN0CgAiY=
github.com/Rocket-Rescue-Node/guarded-beacon-proxy v0.1.1/go.mod h1:p4CMEZjb+V4hI6vaAoOTplAi6pZLHCtnw163NdMztgo=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw=
github.com/VictoriaMetrics/fastcache v1.12.0 h1:vnVi/y9yKDcD9akmc4NqAoqgQhJrOwUF+j9LTgn4QDE=
Expand Down
50 changes: 27 additions & 23 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,20 @@ import (
var logger *zap.Logger

type config struct {
BeaconURL *url.URL
ExecutionURL *url.URL
ListenAddr string
APIListenAddr string
AdminListenAddr string
GRPCListenAddr string
GRPCBeaconAddr string
GRPCTLSCertFile string
GRPCTLSKeyFile string
RocketStorageAddr string
CredentialSecret string
AuthValidityWindow time.Duration
CachePath string
BeaconURL *url.URL
ExecutionURL *url.URL
ListenAddr string
APIListenAddr string
AdminListenAddr string
GRPCListenAddr string
GRPCBeaconAddr string
GRPCTLSCertFile string
GRPCTLSKeyFile string
RocketStorageAddr string
CredentialSecret string
AuthValidityWindow time.Duration
CachePath string
EnableSoloValidators bool
}

func initLogger(debug bool) error {
Expand Down Expand Up @@ -68,6 +69,7 @@ func initFlags() (config config) {
credentialSecretFlag := flag.String("hmac-secret", "test-secret", "The secret to use for HMAC")
authValidityWindowFlag := flag.String("auth-valid-for", "360h", "The duration after which a credential should be considered invalid, eg, 360h for 15 days")
cachePathFlag := flag.String("cache-path", "", "A path to cache EL data in. Leave blank to disable caching.")
enableSoloValidatorsFlag := flag.Bool("enable-solo-validators", true, "Whether or not to allow solo validators access.")

flag.Parse()

Expand Down Expand Up @@ -175,6 +177,7 @@ func initFlags() (config config) {
config.GRPCBeaconAddr = *grpcBeaconAddrFlag
config.ListenAddr = *addrURLFlag
config.RocketStorageAddr = *rocketStorageAddrFlag
config.EnableSoloValidators = *enableSoloValidatorsFlag
return
}

Expand Down Expand Up @@ -276,16 +279,17 @@ func main() {

// Spin up the server on a different goroutine, since it blocks.
r := &router.ProxyRouter{
Addr: config.ListenAddr,
BeaconURL: config.BeaconURL,
GRPCAddr: config.GRPCListenAddr,
GRPCBeaconURL: config.GRPCBeaconAddr,
TLSCertFile: config.GRPCTLSCertFile,
TLSKeyFile: config.GRPCTLSKeyFile,
Logger: logger,
EL: el,
CL: cl,
AuthValidityWindow: config.AuthValidityWindow,
Addr: config.ListenAddr,
BeaconURL: config.BeaconURL,
GRPCAddr: config.GRPCListenAddr,
GRPCBeaconURL: config.GRPCBeaconAddr,
TLSCertFile: config.GRPCTLSCertFile,
TLSKeyFile: config.GRPCTLSKeyFile,
Logger: logger,
EL: el,
CL: cl,
AuthValidityWindow: config.AuthValidityWindow,
EnableSoloValidators: config.EnableSoloValidators,
}
go func() {
logger.Info("Starting http server", zap.String("url", config.ListenAddr))
Expand Down
31 changes: 20 additions & 11 deletions router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ import (
)

type ProxyRouter struct {
Addr string
BeaconURL *url.URL
GRPCAddr string
GRPCBeaconURL string
TLSCertFile string
TLSKeyFile string
Logger *zap.Logger
EL *executionlayer.ExecutionLayer
CL *consensuslayer.ConsensusLayer
AuthValidityWindow time.Duration
Addr string
BeaconURL *url.URL
GRPCAddr string
GRPCBeaconURL string
TLSCertFile string
TLSKeyFile string
Logger *zap.Logger
EL *executionlayer.ExecutionLayer
CL *consensuslayer.ConsensusLayer
AuthValidityWindow time.Duration
EnableSoloValidators bool

gbp *gbp.GuardedBeaconProxy
m *metrics.MetricsRegistry
Expand All @@ -49,7 +50,7 @@ func (pr *ProxyRouter) pbpGuardSolo(withdrawalAddress common.Address, proposers
// Solo validators building local blocks must use their withdrawal address as their fee recipient
if !strings.EqualFold(withdrawalAddress.String(), proposer.FeeRecipient) {
pr.m.Counter("prepare_beacon_incorrect_fee_recipient_solo").Inc()
return gbp.Conflict, fmt.Errorf("Solo validator fee recipient didn't match 0x01 credential for validator %s: expected %s",
return gbp.Conflict, fmt.Errorf("solo validator fee recipient didn't match 0x01 credential for validator %s: expected %s",
proposer.ValidatorIndex, withdrawalAddress.String())
}

Expand Down Expand Up @@ -279,6 +280,10 @@ func (pr *ProxyRouter) authenticate(r *http.Request) (gbp.AuthenticationStatus,
if ac.Credential.OperatorType == pb.OperatorType_OT_ROCKETPOOL {
pr.m.Counter("auth_ok").Inc()
} else {
// If we're dropping solo traffic, 429 it here
if !pr.EnableSoloValidators {
return gbp.TooManyRequests, nil, fmt.Errorf("solo validator support was manually disabled, but may be restored later")
}
pr.m.Counter("auth_ok_solo").Inc()
}
pr.Logger.Debug("Proxying Guarded URI", zap.String("uri", r.RequestURI))
Expand Down Expand Up @@ -312,6 +317,10 @@ func (pr *ProxyRouter) grpcAuthenticate(md metadata.MD) (gbp.AuthenticationStatu
}

if ac.Credential.OperatorType == pb.OperatorType_OT_ROCKETPOOL {
// If we're dropping solo traffic, 429 it here
if !pr.EnableSoloValidators {
return gbp.TooManyRequests, nil, fmt.Errorf("solo validator support was manually disabled, but may be restored later")
}
pr.gm.Counter("auth_ok").Inc()
} else {
pr.gm.Counter("auth_ok_solo").Inc()
Expand Down