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

Commit 24deacd

Browse files
authored
Add builder submission offset flag and update default submission offset from end of slot to 3 seconds (#80)
* Based on data analysis, we find that validators make a getHeader call near the end of the slot * The activity of other builders indicates submissions coalesce around t-3 to t+1, where t is the end of the slot * Currently, Flashbots builder submits starting at t-4. * This was always meant to be a temporary measure to make sure we don't risk the stability of existing builder by inducing too late a submission. * This task adds support for changing the submission to t-3 and exposes configurable CLI and environment variable parameters for builder submission offset.
1 parent 351b040 commit 24deacd

File tree

6 files changed

+107
-65
lines changed

6 files changed

+107
-65
lines changed

README.md

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ $ geth --help
4848
--builder.block_resubmit_interval value (default: "500ms")
4949
Determines the interval at which builder will resubmit block submissions
5050
[$FLASHBOTS_BUILDER_RATE_LIMIT_RESUBMIT_INTERVAL]
51-
51+
5252
--builder.cancellations (default: false)
5353
Enable cancellations for the builder
54-
54+
5555
--builder.dry-run (default: false)
5656
Builder only validates blocks without submission to the relay
5757
@@ -75,15 +75,16 @@ $ geth --help
7575
Disable the bundle fetcher
7676
7777
--builder.rate_limit_duration value (default: "500ms")
78-
Determines rate limit of events processed by builder; a duration string is a
79-
possibly signed sequence of decimal numbers, each with optional fraction and a
80-
unit suffix, such as "300ms", "-1.5h" or "2h45m"
78+
Determines rate limit of events processed by builder. For example, a value of
79+
"500ms" denotes that the builder processes events every 500ms. A duration string
80+
is a possibly signed sequence of decimal numbers, each with optional fraction
81+
and a unit suffix, such as "300ms", "-1.5h" or "2h45m"
8182
[$FLASHBOTS_BUILDER_RATE_LIMIT_DURATION]
82-
83+
8384
--builder.rate_limit_max_burst value (default: 10)
8485
Determines the maximum number of burst events the builder can accommodate at any
8586
given point in time. [$FLASHBOTS_BUILDER_RATE_LIMIT_MAX_BURST]
86-
87+
8788
--builder.relay_secret_key value (default: "0x2fc12ae741f29701f8e30f5de6350766c020cb80768a0ff01e6838ffd2431e11")
8889
Builder local relay API key used for signing headers [$BUILDER_RELAY_SECRET_KEY]
8990
@@ -105,6 +106,12 @@ $ geth --help
105106
--builder.slots_in_epoch value (default: 32)
106107
Set the number of slots in an epoch in the local relay
107108
109+
--builder.submission_offset value (default: 3s)
110+
Determines the offset from the end of slot time that the builder will submit
111+
blocks. For example, if a slot is 12 seconds long, and the offset is 2 seconds,
112+
the builder will submit blocks at 10 seconds into the slot.
113+
[$FLASHBOTS_BUILDER_SUBMISSION_OFFSET]
114+
108115
--builder.validation_blacklist value
109116
Path to file containing blacklisted addresses, json-encoded list of strings
110117

builder/builder.go

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const (
3434
RateLimitBurstDefault = 10
3535
BlockResubmitIntervalDefault = 500 * time.Millisecond
3636

37-
SubmissionDelaySecondsDefault = 4 * time.Second
37+
SubmissionOffsetFromEndOfSlotSecondsDefault = 3 * time.Second
3838
)
3939

4040
type PubkeyHex string
@@ -73,7 +73,8 @@ type Builder struct {
7373
builderSigningDomain phase0.Domain
7474
builderResubmitInterval time.Duration
7575

76-
limiter *rate.Limiter
76+
limiter *rate.Limiter
77+
submissionOffsetFromEndOfSlot time.Duration
7778

7879
slotMu sync.Mutex
7980
slotAttrs types.BuilderPayloadAttributes
@@ -85,16 +86,17 @@ type Builder struct {
8586

8687
// BuilderArgs is a struct that contains all the arguments needed to create a new Builder
8788
type BuilderArgs struct {
88-
sk *bls.SecretKey
89-
ds flashbotsextra.IDatabaseService
90-
relay IRelay
91-
builderSigningDomain phase0.Domain
92-
builderBlockResubmitInterval time.Duration
93-
eth IEthereumService
94-
dryRun bool
95-
ignoreLatePayloadAttributes bool
96-
validator *blockvalidation.BlockValidationAPI
97-
beaconClient IBeaconClient
89+
sk *bls.SecretKey
90+
ds flashbotsextra.IDatabaseService
91+
relay IRelay
92+
builderSigningDomain phase0.Domain
93+
builderBlockResubmitInterval time.Duration
94+
eth IEthereumService
95+
dryRun bool
96+
ignoreLatePayloadAttributes bool
97+
validator *blockvalidation.BlockValidationAPI
98+
beaconClient IBeaconClient
99+
submissionOffsetFromEndOfSlot time.Duration
98100

99101
limiter *rate.Limiter
100102
}
@@ -117,19 +119,24 @@ func NewBuilder(args BuilderArgs) (*Builder, error) {
117119
args.builderBlockResubmitInterval = BlockResubmitIntervalDefault
118120
}
119121

122+
if args.submissionOffsetFromEndOfSlot == 0 {
123+
args.submissionOffsetFromEndOfSlot = SubmissionOffsetFromEndOfSlotSecondsDefault
124+
}
125+
120126
slotCtx, slotCtxCancel := context.WithCancel(context.Background())
121127
return &Builder{
122-
ds: args.ds,
123-
relay: args.relay,
124-
eth: args.eth,
125-
dryRun: args.dryRun,
126-
ignoreLatePayloadAttributes: args.ignoreLatePayloadAttributes,
127-
validator: args.validator,
128-
beaconClient: args.beaconClient,
129-
builderSecretKey: args.sk,
130-
builderPublicKey: pk,
131-
builderSigningDomain: args.builderSigningDomain,
132-
builderResubmitInterval: args.builderBlockResubmitInterval,
128+
ds: args.ds,
129+
relay: args.relay,
130+
eth: args.eth,
131+
dryRun: args.dryRun,
132+
ignoreLatePayloadAttributes: args.ignoreLatePayloadAttributes,
133+
validator: args.validator,
134+
beaconClient: args.beaconClient,
135+
builderSecretKey: args.sk,
136+
builderPublicKey: pk,
137+
builderSigningDomain: args.builderSigningDomain,
138+
builderResubmitInterval: args.builderBlockResubmitInterval,
139+
submissionOffsetFromEndOfSlot: args.submissionOffsetFromEndOfSlot,
133140

134141
limiter: args.limiter,
135142
slotCtx: slotCtx,
@@ -423,7 +430,7 @@ func (b *Builder) runBuildingJob(slotCtx context.Context, proposerPubkey phase0.
423430
// Avoid submitting early into a given slot. For example if slots have 12 second interval, submissions should
424431
// not begin until 8 seconds into the slot.
425432
slotTime := time.Unix(int64(attrs.Timestamp), 0).UTC()
426-
slotSubmitStartTime := slotTime.Add(-SubmissionDelaySecondsDefault)
433+
slotSubmitStartTime := slotTime.Add(-b.submissionOffsetFromEndOfSlot)
427434

428435
// Empties queue, submits the best block for current job with rate limit (global for all jobs)
429436
go runResubmitLoop(ctx, b.limiter, queueSignal, submitBestBlock, slotSubmitStartTime)

builder/config.go

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,31 @@
11
package builder
22

3+
import "time"
4+
35
type Config struct {
4-
Enabled bool `toml:",omitempty"`
5-
EnableValidatorChecks bool `toml:",omitempty"`
6-
EnableLocalRelay bool `toml:",omitempty"`
7-
SlotsInEpoch uint64 `toml:",omitempty"`
8-
SecondsInSlot uint64 `toml:",omitempty"`
9-
DisableBundleFetcher bool `toml:",omitempty"`
10-
DryRun bool `toml:",omitempty"`
11-
IgnoreLatePayloadAttributes bool `toml:",omitempty"`
12-
BuilderSecretKey string `toml:",omitempty"`
13-
RelaySecretKey string `toml:",omitempty"`
14-
ListenAddr string `toml:",omitempty"`
15-
GenesisForkVersion string `toml:",omitempty"`
16-
BellatrixForkVersion string `toml:",omitempty"`
17-
GenesisValidatorsRoot string `toml:",omitempty"`
18-
BeaconEndpoints []string `toml:",omitempty"`
19-
RemoteRelayEndpoint string `toml:",omitempty"`
20-
SecondaryRemoteRelayEndpoints []string `toml:",omitempty"`
21-
ValidationBlocklist string `toml:",omitempty"`
22-
BuilderRateLimitDuration string `toml:",omitempty"`
23-
BuilderRateLimitMaxBurst int `toml:",omitempty"`
24-
BuilderRateLimitResubmitInterval string `toml:",omitempty"`
25-
EnableCancellations bool `toml:",omitempty"`
6+
Enabled bool `toml:",omitempty"`
7+
EnableValidatorChecks bool `toml:",omitempty"`
8+
EnableLocalRelay bool `toml:",omitempty"`
9+
SlotsInEpoch uint64 `toml:",omitempty"`
10+
SecondsInSlot uint64 `toml:",omitempty"`
11+
DisableBundleFetcher bool `toml:",omitempty"`
12+
DryRun bool `toml:",omitempty"`
13+
IgnoreLatePayloadAttributes bool `toml:",omitempty"`
14+
BuilderSecretKey string `toml:",omitempty"`
15+
RelaySecretKey string `toml:",omitempty"`
16+
ListenAddr string `toml:",omitempty"`
17+
GenesisForkVersion string `toml:",omitempty"`
18+
BellatrixForkVersion string `toml:",omitempty"`
19+
GenesisValidatorsRoot string `toml:",omitempty"`
20+
BeaconEndpoints []string `toml:",omitempty"`
21+
RemoteRelayEndpoint string `toml:",omitempty"`
22+
SecondaryRemoteRelayEndpoints []string `toml:",omitempty"`
23+
ValidationBlocklist string `toml:",omitempty"`
24+
BuilderRateLimitDuration string `toml:",omitempty"`
25+
BuilderRateLimitMaxBurst int `toml:",omitempty"`
26+
BuilderRateLimitResubmitInterval string `toml:",omitempty"`
27+
BuilderSubmissionOffset time.Duration `toml:",omitempty"`
28+
EnableCancellations bool `toml:",omitempty"`
2629
}
2730

2831
// DefaultConfig is the default config for the builder.

builder/service.go

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,18 @@ func Register(stack *node.Node, backend *eth.Ethereum, cfg *Config) error {
238238
builderRateLimitInterval = RateLimitIntervalDefault
239239
}
240240

241+
var submissionOffset time.Duration
242+
if offset := cfg.BuilderSubmissionOffset; offset != 0 {
243+
if offset < 0 {
244+
return fmt.Errorf("builder submission offset must be positive")
245+
} else if uint64(offset.Seconds()) > cfg.SecondsInSlot {
246+
return fmt.Errorf("builder submission offset must be less than seconds in slot")
247+
}
248+
submissionOffset = offset
249+
} else {
250+
submissionOffset = SubmissionOffsetFromEndOfSlotSecondsDefault
251+
}
252+
241253
// TODO: move to proper flags
242254
var ds flashbotsextra.IDatabaseService
243255
dbDSN := os.Getenv("FLASHBOTS_POSTGRES_DSN")
@@ -269,17 +281,18 @@ func Register(stack *node.Node, backend *eth.Ethereum, cfg *Config) error {
269281
}
270282

271283
builderArgs := BuilderArgs{
272-
sk: builderSk,
273-
ds: ds,
274-
relay: relay,
275-
builderSigningDomain: builderSigningDomain,
276-
builderBlockResubmitInterval: builderRateLimitInterval,
277-
eth: ethereumService,
278-
dryRun: cfg.DryRun,
279-
ignoreLatePayloadAttributes: cfg.IgnoreLatePayloadAttributes,
280-
validator: validator,
281-
beaconClient: beaconClient,
282-
limiter: limiter,
284+
sk: builderSk,
285+
ds: ds,
286+
dryRun: cfg.DryRun,
287+
eth: ethereumService,
288+
relay: relay,
289+
builderSigningDomain: builderSigningDomain,
290+
builderBlockResubmitInterval: builderRateLimitInterval,
291+
submissionOffsetFromEndOfSlot: submissionOffset,
292+
ignoreLatePayloadAttributes: cfg.IgnoreLatePayloadAttributes,
293+
validator: validator,
294+
beaconClient: beaconClient,
295+
limiter: limiter,
283296
}
284297

285298
builderBackend, err := NewBuilder(builderArgs)

cmd/geth/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ var (
178178
utils.BuilderRateLimitDuration,
179179
utils.BuilderRateLimitMaxBurst,
180180
utils.BuilderBlockResubmitInterval,
181+
utils.BuilderSubmissionOffset,
181182
utils.BuilderEnableCancellations,
182183
}
183184

cmd/utils/flags.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,8 @@ var (
809809

810810
BuilderRateLimitDuration = &cli.StringFlag{
811811
Name: "builder.rate_limit_duration",
812-
Usage: "Determines rate limit of events processed by builder; a duration string is a possibly signed sequence " +
812+
Usage: "Determines rate limit of events processed by builder. For example, a value of \"500ms\" denotes that the builder processes events every 500ms. " +
813+
"A duration string is a possibly signed sequence " +
813814
"of decimal numbers, each with optional fraction and a unit suffix, such as \"300ms\", \"-1.5h\" or \"2h45m\"",
814815
EnvVars: []string{"FLASHBOTS_BUILDER_RATE_LIMIT_DURATION"},
815816
Value: builder.RateLimitIntervalDefault.String(),
@@ -835,6 +836,15 @@ var (
835836
Category: flags.BuilderCategory,
836837
}
837838

839+
BuilderSubmissionOffset = &cli.DurationFlag{
840+
Name: "builder.submission_offset",
841+
Usage: "Determines the offset from the end of slot time that the builder will submit blocks. " +
842+
"For example, if a slot is 12 seconds long, and the offset is 2 seconds, the builder will submit blocks at 10 seconds into the slot.",
843+
EnvVars: []string{"FLASHBOTS_BUILDER_SUBMISSION_OFFSET"},
844+
Value: builder.SubmissionOffsetFromEndOfSlotSecondsDefault,
845+
Category: flags.BuilderCategory,
846+
}
847+
838848
BuilderEnableCancellations = &cli.BoolFlag{
839849
Name: "builder.cancellations",
840850
Usage: "Enable cancellations for the builder",
@@ -1657,6 +1667,7 @@ func SetBuilderConfig(ctx *cli.Context, cfg *builder.Config) {
16571667
cfg.ValidationBlocklist = ctx.String(BuilderBlockValidationBlacklistSourceFilePath.Name)
16581668
cfg.BuilderRateLimitDuration = ctx.String(BuilderRateLimitDuration.Name)
16591669
cfg.BuilderRateLimitMaxBurst = ctx.Int(BuilderRateLimitMaxBurst.Name)
1670+
cfg.BuilderSubmissionOffset = ctx.Duration(BuilderSubmissionOffset.Name)
16601671
cfg.EnableCancellations = ctx.IsSet(BuilderEnableCancellations.Name)
16611672
}
16621673

0 commit comments

Comments
 (0)