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

Measure builder payload bytes #25

Merged
merged 1 commit into from
Aug 21, 2024
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
14 changes: 14 additions & 0 deletions op-node/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ type Metricer interface {
RecordBuilderRequestTime(duration time.Duration)
RecordBuilderRequestFail()
RecordBuilderRequestTimeout()
RecordBuilderPayloadBytes(num int)
RecordSequencerProfit(profit float64, source PayloadSource)
RecordSequencerPayloadInserted(source PayloadSource)
RecordPayloadGas(gas float64, source string)
Expand Down Expand Up @@ -131,6 +132,7 @@ type Metrics struct {
SequencerBuilderRequestTotal prometheus.Counter
SequencerBuilderRequestErrors prometheus.Counter
SequencerBuilderRequestTimeouts prometheus.Counter
SequencerBuilderPayloadBytes prometheus.Gauge

SequencerProfit *prometheus.GaugeVec

Expand Down Expand Up @@ -423,6 +425,11 @@ func NewMetrics(procName string) *Metrics {
Name: "sequencer_builder_request_timeout",
Help: "Number of sequencer builder request timeouts",
}),
SequencerBuilderPayloadBytes: factory.NewGauge(prometheus.GaugeOpts{
Namespace: ns,
Name: "sequencer_builder_payload_bytes",
Help: "Size of sequencer builder payloads by source",
}),
SequencerProfit: factory.NewGaugeVec(prometheus.GaugeOpts{
Namespace: ns,
Name: "sequencer_profit",
Expand Down Expand Up @@ -637,6 +644,10 @@ func (m *Metrics) RecordBuilderRequestTimeout() {
m.SequencerBuilderRequestTimeouts.Inc()
}

func (m *Metrics) RecordBuilderPayloadBytes(num int) {
m.SequencerBuilderPayloadBytes.Add(float64(num))
}

// RecordSequencerProfit measures the profit made by the sequencer by source: engine and external builders.
func (m *Metrics) RecordSequencerProfit(profit float64, source PayloadSource) {
m.SequencerProfit.WithLabelValues(string(source)).Set(profit)
Expand Down Expand Up @@ -828,6 +839,9 @@ func (n *noopMetricer) RecordBuilderRequestFail() {
func (n *noopMetricer) RecordBuilderRequestTimeout() {
}

func (n *noopMetricer) RecordBuilderPayloadBytes(num int) {
}

func (n *noopMetricer) RecordSequencerProfit(profit float64, source PayloadSource) {
}

Expand Down
10 changes: 9 additions & 1 deletion op-node/node/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/holiman/uint256"

"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup/builder"
"github.com/ethereum-optimism/optimism/op-service/client"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum/go-ethereum/common"
Expand All @@ -37,6 +38,10 @@ type BuilderAPIClient struct {
httpClient *client.BasicHTTPClient
}

type BuilderMetrics interface {
RecordBuilderPayloadBytes(num int)
}

func NewBuilderClient(log log.Logger, rollupCfg *rollup.Config, endpoint string, timeout time.Duration) *BuilderAPIClient {
httpClient := client.NewBasicHTTPClient(endpoint, log)
config := &BuilderAPIConfig{
Expand All @@ -60,12 +65,14 @@ func (s *BuilderAPIClient) Timeout() time.Duration {
return s.config.Timeout
}

var _ builder.PayloadBuilder = &BuilderAPIClient{}

type httpErrorResp struct {
Code int `json:"code"`
Message string `json:"message"`
}

func (s *BuilderAPIClient) GetPayload(ctx context.Context, ref eth.L2BlockRef, log log.Logger) (*eth.ExecutionPayloadEnvelope, error) {
func (s *BuilderAPIClient) GetPayload(ctx context.Context, ref eth.L2BlockRef, log log.Logger, metrics builder.BuilderMetrics) (*eth.ExecutionPayloadEnvelope, error) {
submitBlockRequest := new(builderSpec.VersionedSubmitBlockRequest)
slot := ref.Number + 1
parentHash := ref.Hash
Expand All @@ -85,6 +92,7 @@ func (s *BuilderAPIClient) GetPayload(ctx context.Context, ref eth.L2BlockRef, l
}

if resp.StatusCode != http.StatusOK {
metrics.RecordBuilderPayloadBytes(len(bodyBytes))
var errResp httpErrorResp
if err := json.Unmarshal(bodyBytes, &errResp); err != nil {
log.Warn("failed to unmarshal error response", "error", err, "response", string(bodyBytes))
Expand Down
10 changes: 8 additions & 2 deletions op-node/rollup/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@ import (
"github.com/ethereum/go-ethereum/log"
)

type BuilderMetrics interface {
RecordBuilderPayloadBytes(num int)
}

type PayloadBuilder interface {
Enabled() bool
Timeout() time.Duration
GetPayload(ctx context.Context, ref eth.L2BlockRef, log log.Logger) (*eth.ExecutionPayloadEnvelope, error)
GetPayload(ctx context.Context, ref eth.L2BlockRef, log log.Logger, metrics BuilderMetrics) (*eth.ExecutionPayloadEnvelope, error)
}

type NoOpBuilder struct{}

func (n *NoOpBuilder) GetPayload(_ context.Context, _ eth.L2BlockRef, _ log.Logger) (*eth.ExecutionPayloadEnvelope, error) {
func (n *NoOpBuilder) GetPayload(_ context.Context, _ eth.L2BlockRef, _ log.Logger, _ BuilderMetrics) (*eth.ExecutionPayloadEnvelope, error) {
return nil, errors.New("Builder not enabled")
}

Expand All @@ -28,3 +32,5 @@ func (n *NoOpBuilder) Enabled() bool {
func (n *NoOpBuilder) Timeout() time.Duration {
return 0
}

var _ PayloadBuilder = &NoOpBuilder{}
2 changes: 1 addition & 1 deletion op-node/rollup/derive/engine_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ type PayloadRequestResult struct {

func requestPayloadFromBuilder(ctx context.Context, builder builder.PayloadBuilder, l2head eth.L2BlockRef, log log.Logger, metrics Metrics, results chan<- *PayloadRequestResult) {
start := time.Now()
payload, err := builder.GetPayload(ctx, l2head, log)
payload, err := builder.GetPayload(ctx, l2head, log, metrics)
metrics.RecordBuilderRequestTime(time.Since(start))
if err != nil {
results <- &PayloadRequestResult{success: false, error: err}
Expand Down
1 change: 1 addition & 0 deletions op-node/rollup/derive/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type Metrics interface {
RecordBuilderRequestTime(duration time.Duration)
RecordBuilderRequestFail()
RecordBuilderRequestTimeout()
RecordBuilderPayloadBytes(num int)
RecordSequencerProfit(profit float64, source metrics.PayloadSource)
RecordSequencerPayloadInserted(source metrics.PayloadSource)
RecordPayloadGas(gas float64, source string)
Expand Down
1 change: 1 addition & 0 deletions op-node/rollup/driver/sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type SequencerMetrics interface {
RecordBuilderRequestTime(duration time.Duration)
RecordBuilderRequestFail()
RecordBuilderRequestTimeout()
RecordBuilderPayloadBytes(num int)
RecordSequencerProfit(profit float64, source metrics.PayloadSource)
RecordSequencerPayloadInserted(source metrics.PayloadSource)
RecordPayloadGas(gas float64, source string)
Expand Down