Skip to content

Commit

Permalink
Add channel to notify externally of new validators
Browse files Browse the repository at this point in the history
  • Loading branch information
ferranbt committed Jul 5, 2024
1 parent 7dc9c0d commit d7b62c1
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
8 changes: 8 additions & 0 deletions datastore/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,14 @@ func (ds *Datastore) NumRegisteredValidators() (uint64, error) {
return ds.db.NumRegisteredValidators()
}

func (ds *Datastore) SetKnownValidator(pubkeyHex common.PubkeyHex, index uint64) {
ds.knownValidatorsLock.Lock()
defer ds.knownValidatorsLock.Unlock()

ds.knownValidatorsByPubkey[pubkeyHex] = index
ds.knownValidatorsByIndex[index] = pubkeyHex
}

// SaveValidatorRegistration saves a validator registration into both Redis and the database
func (ds *Datastore) SaveValidatorRegistration(entry builderApiV1.SignedValidatorRegistration) error {
// First save in the database
Expand Down
16 changes: 15 additions & 1 deletion services/api/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ type RelayAPI struct {

validatorRegC chan builderApiV1.SignedValidatorRegistration

// used to notify when a new validator has been registered
validatorUpdateCh chan struct{}

// used to wait on any active getPayload calls on shutdown
getPayloadCallsInFlight sync.WaitGroup

Expand Down Expand Up @@ -293,7 +296,8 @@ func NewRelayAPI(opts RelayAPIOpts) (api *RelayAPI, err error) {
proposerDutiesResponse: &[]byte{},
blockSimRateLimiter: NewBlockSimulationRateLimiter(opts.BlockSimURL),

validatorRegC: make(chan builderApiV1.SignedValidatorRegistration, 450_000),
validatorRegC: make(chan builderApiV1.SignedValidatorRegistration, 450_000),
validatorUpdateCh: make(chan struct{}),
}

if os.Getenv("FORCE_GET_HEADER_204") == "1" {
Expand Down Expand Up @@ -554,6 +558,10 @@ func (api *RelayAPI) StopServer() (err error) {
return api.srv.Shutdown(context.Background())
}

func (api *RelayAPI) ValidatorUpdateCh() chan struct{} {
return api.validatorUpdateCh
}

func (api *RelayAPI) isCapella(slot uint64) bool {
return hasReachedFork(slot, api.capellaEpoch) && !hasReachedFork(slot, api.denebEpoch)
}
Expand Down Expand Up @@ -1114,6 +1122,12 @@ func (api *RelayAPI) handleRegisterValidator(w http.ResponseWriter, req *http.Re
default:
regLog.Error("validator registration channel full")
}

// notify of a new validator
select {
case api.validatorUpdateCh <- struct{}{}:
default:
}
})

log = log.WithFields(logrus.Fields{
Expand Down
22 changes: 22 additions & 0 deletions services/api/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,28 @@ func TestRegisterValidator(t *testing.T) {
rr := backend.request(http.MethodPost, path, []builderApiV1.SignedValidatorRegistration{common.ValidPayloadRegisterValidator})
require.Equal(t, http.StatusBadRequest, rr.Code)
})

t.Run("known validator", func(t *testing.T) {
backend := newTestBackend(t, 1)

msg := common.ValidPayloadRegisterValidator
backend.datastore.SetKnownValidator(common.PubkeyHex(msg.Message.Pubkey.String()), 1)

rr := backend.request(http.MethodPost, path, []builderApiV1.SignedValidatorRegistration{common.ValidPayloadRegisterValidator})
require.Equal(t, http.StatusOK, rr.Code)

// wait for the both channel notifications
select {
case val := <-backend.relay.validatorRegC:
require.Equal(t, val.Message.Pubkey, msg.Message.Pubkey)
default:
}

select {
case <-backend.relay.validatorUpdateCh:
default:
}
})
}

func TestGetHeader(t *testing.T) {
Expand Down

0 comments on commit d7b62c1

Please sign in to comment.