Skip to content
This repository was archived by the owner on Oct 25, 2024. It is now read-only.

Commit c7b1c83

Browse files
committed
add timer for updating known validators
1 parent 01c40c5 commit c7b1c83

File tree

10 files changed

+80
-19
lines changed

10 files changed

+80
-19
lines changed

builder/beacon_client.go

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"net/http"
99
"strconv"
1010
"sync"
11+
"time"
1112

1213
"github.com/ethereum/go-ethereum/common"
1314
"github.com/ethereum/go-ethereum/common/hexutil"
@@ -29,21 +30,28 @@ func (b *testBeaconClient) onForkchoiceUpdate() (uint64, error) {
2930
return b.slot, nil
3031
}
3132

33+
func (b *testBeaconClient) updateValidatorsMap() error {
34+
return nil
35+
}
36+
3237
type BeaconClient struct {
3338
endpoint string
3439
slotsInEpoch uint64
40+
secondsInSlot uint64
3541

3642
mu sync.Mutex
3743
currentEpoch uint64
3844
currentSlot uint64
3945
nextSlotProposer PubkeyHex
4046
slotProposerMap map[uint64]PubkeyHex
47+
slotRequestedCh chan uint64
4148
}
4249

43-
func NewBeaconClient(endpoint string, slotsInEpoch uint64) *BeaconClient {
50+
func NewBeaconClient(endpoint string, slotsInEpoch uint64, secondsInSlot uint64) *BeaconClient {
4451
return &BeaconClient{
4552
endpoint: endpoint,
4653
slotsInEpoch: slotsInEpoch,
54+
secondsInSlot: secondsInSlot,
4755
slotProposerMap: make(map[uint64]PubkeyHex),
4856
}
4957
}
@@ -56,8 +64,6 @@ func (b *BeaconClient) getProposerForNextSlot(requestedSlot uint64) (PubkeyHex,
5664
b.mu.Lock()
5765
defer b.mu.Unlock()
5866

59-
go b.updateValidatorsMap(requestedSlot)
60-
6167
nextSlotProposer, found := b.slotProposerMap[requestedSlot]
6268
if !found {
6369
log.Error("inconsistent proposer mapping", "currentSlot", b.currentSlot, "slotProposerMap", b.slotProposerMap)
@@ -66,20 +72,42 @@ func (b *BeaconClient) getProposerForNextSlot(requestedSlot uint64) (PubkeyHex,
6672
return nextSlotProposer, nil
6773
}
6874

69-
func (b *BeaconClient) updateValidatorsMap(nextSlot uint64) error {
70-
b.currentSlot = nextSlot
71-
nextSlotEpoch := nextSlot / b.slotsInEpoch
72-
// if slot at half epoch, fetch next epoch's proposers
73-
if nextSlotEpoch != b.currentEpoch || nextSlot%b.slotsInEpoch == b.slotsInEpoch/2 {
74-
slotProposerMap, err := fetchEpochProposersMap(b.endpoint, nextSlotEpoch)
75-
if err != nil {
76-
return err
75+
func (b *BeaconClient) updateValidatorsMap() error {
76+
// Start regular slot updates
77+
slotsPerEpoch := b.slotsInEpoch
78+
durationPerSlot := time.Duration(b.secondsInSlot) * time.Second
79+
durationPerEpoch := durationPerSlot * time.Duration(slotsPerEpoch)
80+
b.slotRequestedCh = make(chan uint64)
81+
// Every half epoch request validators map
82+
timer := time.NewTicker(durationPerEpoch/2)
83+
for {
84+
select {
85+
case slot := <-b.slotRequestedCh:
86+
b.currentSlot = slot
87+
nextSlotEpoch := slot / b.slotsInEpoch
88+
// if slot at half epoch, fetch next epoch's proposers
89+
if nextSlotEpoch > b.currentEpoch {
90+
slotProposerMap, err := fetchEpochProposersMap(b.endpoint, nextSlotEpoch)
91+
if err != nil {
92+
log.Error("could not fetch validators map", "err", err)
93+
continue
94+
}
95+
96+
b.slotProposerMap = slotProposerMap
97+
b.currentEpoch = nextSlotEpoch
98+
b.slotProposerMap = slotProposerMap
99+
timer.Reset(durationPerEpoch/2)
100+
}
101+
case <-timer.C:
102+
slotProposerMap, err := fetchEpochProposersMap(b.endpoint, b.currentEpoch+1)
103+
if err != nil {
104+
log.Error("could not fetch validators map", "err", err)
105+
continue
106+
}
107+
b.slotProposerMap = slotProposerMap
108+
timer.Reset(durationPerEpoch/2)
77109
}
78-
79-
b.currentEpoch = nextSlotEpoch
80-
b.slotProposerMap = slotProposerMap
81110
}
82-
83111
return nil
84112
}
85113

builder/beacon_client_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ func TestOnForkchoiceUpdate(t *testing.T) {
203203
]
204204
}`)
205205

206-
bc := NewBeaconClient(mbn.srv.URL)
206+
bc := NewBeaconClient(mbn.srv.URL, 32, 12)
207207
slot, err := bc.onForkchoiceUpdate()
208208
require.NoError(t, err)
209209
require.Equal(t, slot, uint64(32))
@@ -221,7 +221,7 @@ func TestOnForkchoiceUpdate(t *testing.T) {
221221
mbn.headersCode = 404
222222
mbn.headersResp = []byte(`{ "code": 404, "message": "State not found" }`)
223223

224-
slot, err = NewBeaconClient(mbn.srv.URL).onForkchoiceUpdate()
224+
slot, err = NewBeaconClient(mbn.srv.URL, 32, 12).onForkchoiceUpdate()
225225
require.EqualError(t, err, "State not found")
226226
require.Equal(t, slot, uint64(0))
227227

builder/builder.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@ type IBeaconClient interface {
3333
isValidator(pubkey PubkeyHex) bool
3434
getProposerForNextSlot(requestedSlot uint64) (PubkeyHex, error)
3535
onForkchoiceUpdate() (uint64, error)
36+
updateValidatorsMap() error
3637
}
3738

3839
type IRelay interface {
3940
SubmitBlock(msg *boostTypes.BuilderSubmitBlockRequest, vd ValidatorData) error
4041
GetValidatorForSlot(nextSlot uint64) (ValidatorData, error)
42+
Start() error
4143
}
4244

4345
type IBuilder interface {
@@ -89,7 +91,7 @@ func NewBuilder(sk *bls.SecretKey, ds flashbotsextra.IDatabaseService, relay IRe
8991
}
9092

9193
func (b *Builder) Start() error {
92-
return nil
94+
return b.relay.Start()
9395
}
9496

9597
func (b *Builder) Stop() error {

builder/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ type Config struct {
55
EnableValidatorChecks bool `toml:",omitempty"`
66
EnableLocalRelay bool `toml:",omitempty"`
77
SlotsInEpoch uint64 `toml:",omitempty"`
8+
SecondsInSlot uint64 `toml:",omitempty"`
89
DisableBundleFetcher bool `toml:",omitempty"`
910
DryRun bool `toml:",omitempty"`
1011
BuilderSecretKey string `toml:",omitempty"`
@@ -25,6 +26,7 @@ var DefaultConfig = Config{
2526
EnableValidatorChecks: false,
2627
EnableLocalRelay: false,
2728
SlotsInEpoch: 32,
29+
SecondsInSlot: 12,
2830
DisableBundleFetcher: false,
2931
DryRun: false,
3032
BuilderSecretKey: "0x2fc12ae741f29701f8e30f5de6350766c020cb80768a0ff01e6838ffd2431e11",

builder/local_relay.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ func NewLocalRelay(sk *bls.SecretKey, beaconClient IBeaconClient, builderSigning
8484
}
8585
}
8686

87+
func (r *LocalRelay) Start() error {
88+
go r.beaconClient.updateValidatorsMap()
89+
return nil
90+
}
91+
8792
func (r *LocalRelay) SubmitBlock(msg *boostTypes.BuilderSubmitBlockRequest, _ ValidatorData) error {
8893
log.Info("submitting block to local relay", "block", msg.ExecutionPayload.BlockHash.String())
8994
return r.submitBlock(msg)

builder/relay.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ func (r *RemoteRelay) GetValidatorForSlot(nextSlot uint64) (ValidatorData, error
125125
return ValidatorData{}, ErrValidatorNotFound
126126
}
127127

128+
func (r *RemoteRelay) Start() error {
129+
return nil
130+
}
131+
128132
func (r *RemoteRelay) SubmitBlock(msg *boostTypes.BuilderSubmitBlockRequest, _ ValidatorData) error {
129133
log.Info("submitting block to remote relay", "endpoint", r.endpoint)
130134
code, err := server.SendHTTPRequest(context.TODO(), *http.DefaultClient, http.MethodPost, r.endpoint+"/relay/v1/builder/blocks", msg, nil)

builder/relay_aggregator.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ func NewRemoteRelayAggregator(primary IRelay, secondary []IRelay) *RemoteRelayAg
2424
}
2525
}
2626

27+
func (r *RemoteRelayAggregator) Start() error {
28+
for _, relay := range r.relays {
29+
err := relay.Start()
30+
if err != nil {
31+
return err
32+
}
33+
}
34+
return nil
35+
}
36+
2737
func (r *RemoteRelayAggregator) SubmitBlock(msg *boostTypes.BuilderSubmitBlockRequest, registration ValidatorData) error {
2838
r.registrationsCacheLock.RLock()
2939
defer r.registrationsCacheLock.RUnlock()

builder/relay_aggregator_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ func (r *testRelay) GetValidatorForSlot(nextSlot uint64) (ValidatorData, error)
5858
return r.gvsVd, r.gvsErr
5959
}
6060

61+
func (r *testRelay) Start() error {
62+
return nil
63+
}
64+
6165
func TestRemoteRelayAggregator(t *testing.T) {
6266
t.Run("should return error if no relays return validator data", func(t *testing.T) {
6367
backend := newTestRelayAggBackend(3)

builder/service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ func Register(stack *node.Node, backend *eth.Ethereum, cfg *Config) error {
144144
copy(bellatrixForkVersion[:], bellatrixForkVersionBytes[:4])
145145
proposerSigningDomain := boostTypes.ComputeDomain(boostTypes.DomainTypeBeaconProposer, bellatrixForkVersion, genesisValidatorsRoot)
146146

147-
beaconClient := NewBeaconClient(cfg.BeaconEndpoint, cfg.SlotsInEpoch)
147+
beaconClient := NewBeaconClient(cfg.BeaconEndpoint, cfg.SlotsInEpoch, cfg.SecondsInSlot)
148148

149149
var localRelay *LocalRelay
150150
if cfg.EnableLocalRelay {

cmd/utils/flags.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,11 @@ var (
713713
Usage: "Set the number of slots in an epoch in the local relay",
714714
Value: 32,
715715
}
716+
BuilderSecondsInSlot = &cli.Uint64Flag{
717+
Name: "builder.seconds_in_slot",
718+
Usage: "Set the number of seconds in a slot in the local relay",
719+
Value: 12,
720+
}
716721
BuilderDisableBundleFetcher = &cli.BoolFlag{
717722
Name: "builder.no_bundle_fetcher",
718723
Usage: "Disable the bundle fetcher",
@@ -1583,6 +1588,7 @@ func SetBuilderConfig(ctx *cli.Context, cfg *builder.Config) {
15831588
cfg.EnableValidatorChecks = ctx.IsSet(BuilderEnableValidatorChecks.Name)
15841589
cfg.EnableLocalRelay = ctx.IsSet(BuilderEnableLocalRelay.Name)
15851590
cfg.SlotsInEpoch = ctx.Uint64(BuilderSlotsInEpoch.Name)
1591+
cfg.SecondsInSlot = ctx.Uint64(BuilderSecondsInSlot.Name)
15861592
cfg.DisableBundleFetcher = ctx.IsSet(BuilderDisableBundleFetcher.Name)
15871593
cfg.DryRun = ctx.IsSet(BuilderDryRun.Name)
15881594
cfg.BuilderSecretKey = ctx.String(BuilderSecretKey.Name)

0 commit comments

Comments
 (0)