Skip to content

Commit 50641b4

Browse files
authored
send version in useragent header (#213)
1 parent 1940ff6 commit 50641b4

File tree

8 files changed

+71
-36
lines changed

8 files changed

+71
-36
lines changed

cmd/test-cli/beacon.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ type partialSignedBeaconBlock struct {
5353

5454
func getCurrentBeaconBlock(beaconEndpoint string) (beaconBlockData, error) {
5555
var blockResp partialSignedBeaconBlock
56-
_, err := server.SendHTTPRequest(context.TODO(), *http.DefaultClient, http.MethodGet, beaconEndpoint+"/eth/v2/beacon/blocks/head", nil, &blockResp)
56+
_, err := server.SendHTTPRequest(context.TODO(), *http.DefaultClient, http.MethodGet, beaconEndpoint+"/eth/v2/beacon/blocks/head", "test-cli/beacon", nil, &blockResp)
5757
if err != nil {
5858
return beaconBlockData{}, err
5959
}

cmd/test-cli/main.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func doRegisterValidator(v validatorPrivateData, boostEndpoint string, builderSi
3131
if err != nil {
3232
log.WithError(err).Fatal("Could not prepare registration message")
3333
}
34-
_, err = server.SendHTTPRequest(context.TODO(), *http.DefaultClient, http.MethodPost, boostEndpoint+"/eth/v1/builder/validators", message, nil)
34+
_, err = server.SendHTTPRequest(context.TODO(), *http.DefaultClient, http.MethodPost, boostEndpoint+"/eth/v1/builder/validators", "test-cli", message, nil)
3535

3636
if err != nil {
3737
log.WithError(err).Fatal("Validator registration not successful")
@@ -68,7 +68,7 @@ func doGetHeader(v validatorPrivateData, boostEndpoint string, beaconNode Beacon
6868
uri := fmt.Sprintf("%s/eth/v1/builder/header/%d/%s/%s", boostEndpoint, currentBlock.Slot+1, currentBlockHash, v.Pk.String())
6969

7070
var getHeaderResp boostTypes.GetHeaderResponse
71-
if _, err := server.SendHTTPRequest(context.TODO(), *http.DefaultClient, http.MethodGet, uri, nil, &getHeaderResp); err != nil {
71+
if _, err := server.SendHTTPRequest(context.TODO(), *http.DefaultClient, http.MethodGet, uri, "test-cli", nil, &getHeaderResp); err != nil {
7272
log.WithError(err).WithField("currentBlockHash", currentBlockHash).Fatal("Could not get header")
7373
}
7474

@@ -120,7 +120,7 @@ func doGetPayload(v validatorPrivateData, boostEndpoint string, beaconNode Beaco
120120
Signature: signature,
121121
}
122122
var respPayload boostTypes.GetPayloadResponse
123-
if _, err := server.SendHTTPRequest(context.TODO(), *http.DefaultClient, http.MethodPost, boostEndpoint+"/eth/v1/builder/blinded_blocks", payload, &respPayload); err != nil {
123+
if _, err := server.SendHTTPRequest(context.TODO(), *http.DefaultClient, http.MethodPost, boostEndpoint+"/eth/v1/builder/blinded_blocks", "test-cli", payload, &respPayload); err != nil {
124124
log.WithError(err).Fatal("could not get payload")
125125
}
126126

server/relay_entry.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@ func NewRelayEntry(relayURL string) (entry RelayEntry, err error) {
4444
return entry, ErrMissingRelayPubkey
4545
}
4646

47-
q := entry.URL.Query()
48-
q.Set("boost", Version)
49-
entry.URL.RawQuery = q.Encode()
50-
5147
err = entry.PublicKey.UnmarshalText([]byte(entry.URL.User.Username()))
5248
return entry, err
5349
}

server/relay_entry_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ func TestParseRelaysURLs(t *testing.T) {
2626
name: "Relay URL with protocol scheme",
2727
relayURL: fmt.Sprintf("http://%[email protected]", publicKey.String()),
2828

29-
expectedURI: "http://foo.com?boost=dev",
29+
expectedURI: "http://foo.com",
3030
expectedPublicKey: publicKey.String(),
31-
expectedURL: fmt.Sprintf("http://%[email protected]?boost=dev", publicKey.String()),
31+
expectedURL: fmt.Sprintf("http://%[email protected]", publicKey.String()),
3232
},
3333
{
3434
name: "Relay URL without protocol scheme, without public key",
@@ -40,33 +40,33 @@ func TestParseRelaysURLs(t *testing.T) {
4040
name: "Relay URL without protocol scheme and with public key",
4141
relayURL: publicKey.String() + "@foo.com",
4242

43-
expectedURI: "http://foo.com?boost=dev",
43+
expectedURI: "http://foo.com",
4444
expectedPublicKey: publicKey.String(),
45-
expectedURL: "http://" + publicKey.String() + "@foo.com?boost=dev",
45+
expectedURL: "http://" + publicKey.String() + "@foo.com",
4646
},
4747
{
4848
name: "Relay URL with public key host and port",
4949
relayURL: publicKey.String() + "@foo.com:9999",
5050

51-
expectedURI: "http://foo.com:9999?boost=dev",
51+
expectedURI: "http://foo.com:9999",
5252
expectedPublicKey: publicKey.String(),
53-
expectedURL: "http://" + publicKey.String() + "@foo.com:9999?boost=dev",
53+
expectedURL: "http://" + publicKey.String() + "@foo.com:9999",
5454
},
5555
{
5656
name: "Relay URL with IP and port",
5757
relayURL: publicKey.String() + "@12.345.678:9999",
5858

59-
expectedURI: "http://12.345.678:9999?boost=dev",
59+
expectedURI: "http://12.345.678:9999",
6060
expectedPublicKey: publicKey.String(),
61-
expectedURL: "http://" + publicKey.String() + "@12.345.678:9999?boost=dev",
61+
expectedURL: "http://" + publicKey.String() + "@12.345.678:9999",
6262
},
6363
{
6464
name: "Relay URL with https IP and port",
6565
relayURL: "https://" + publicKey.String() + "@12.345.678:9999",
6666

67-
expectedURI: "https://12.345.678:9999?boost=dev",
67+
expectedURI: "https://12.345.678:9999",
6868
expectedPublicKey: publicKey.String(),
69-
expectedURL: "https://" + publicKey.String() + "@12.345.678:9999?boost=dev",
69+
expectedURL: "https://" + publicKey.String() + "@12.345.678:9999",
7070
},
7171
{
7272
name: "Invalid relay public key",
@@ -78,9 +78,9 @@ func TestParseRelaysURLs(t *testing.T) {
7878
name: "Relay URL with query arg",
7979
relayURL: fmt.Sprintf("http://%[email protected]?id=foo&bar=1", publicKey.String()),
8080

81-
expectedURI: "http://foo.com?bar=1&boost=dev&id=foo",
81+
expectedURI: "http://foo.com?id=foo&bar=1",
8282
expectedPublicKey: publicKey.String(),
83-
expectedURL: fmt.Sprintf("http://%[email protected]?bar=1&boost=dev&id=foo", publicKey.String()),
83+
expectedURL: fmt.Sprintf("http://%[email protected]?id=foo&bar=1", publicKey.String()),
8484
},
8585
}
8686

server/service.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,10 @@ func (m *BoostService) handleStatus(w http.ResponseWriter, req *http.Request) {
160160
// If relayCheck is enabled, make sure at least 1 relay returns success
161161
var wg sync.WaitGroup
162162
var numSuccessRequestsToRelay uint32
163+
ua := UserAgent(req.Header.Get("User-Agent"))
163164
ctx, cancel := context.WithCancel(context.Background())
164165
defer cancel()
166+
165167
for _, r := range m.relays {
166168
wg.Add(1)
167169

@@ -171,7 +173,7 @@ func (m *BoostService) handleStatus(w http.ResponseWriter, req *http.Request) {
171173
log := m.log.WithField("url", url)
172174
log.Debug("Checking relay status")
173175

174-
_, err := SendHTTPRequest(ctx, m.httpClient, http.MethodGet, url, nil, nil)
176+
_, err := SendHTTPRequest(ctx, m.httpClient, http.MethodGet, url, ua, nil, nil)
175177
if err != nil && ctx.Err() != context.Canceled {
176178
log.WithError(err).Error("failed to retrieve relay status")
177179
return
@@ -204,27 +206,24 @@ func (m *BoostService) handleRegisterValidator(w http.ResponseWriter, req *http.
204206
return
205207
}
206208

207-
numSuccessRequestsToRelay := 0
208-
var mu sync.Mutex
209-
210-
// Call the relays
211209
var wg sync.WaitGroup
210+
var numSuccessRequestsToRelay uint32
211+
ua := UserAgent(req.Header.Get("User-Agent"))
212+
212213
for _, relay := range m.relays {
213214
wg.Add(1)
214215
go func(relay RelayEntry) {
215216
defer wg.Done()
216217
url := relay.GetURI(pathRegisterValidator)
217218
log := log.WithField("url", url)
218219

219-
_, err := SendHTTPRequest(context.Background(), m.httpClient, http.MethodPost, url, payload, nil)
220+
_, err := SendHTTPRequest(context.Background(), m.httpClient, http.MethodPost, url, ua, payload, nil)
220221
if err != nil {
221222
log.WithError(err).Warn("error in registerValidator to relay")
222223
return
223224
}
224225

225-
mu.Lock()
226-
defer mu.Unlock()
227-
numSuccessRequestsToRelay++
226+
atomic.AddUint32(&numSuccessRequestsToRelay, 1)
228227
}(relay)
229228
}
230229

@@ -269,6 +268,7 @@ func (m *BoostService) handleGetHeader(w http.ResponseWriter, req *http.Request)
269268

270269
result := new(types.GetHeaderResponse)
271270
var mu sync.Mutex
271+
ua := UserAgent(req.Header.Get("User-Agent"))
272272

273273
// Call the relays
274274
var wg sync.WaitGroup
@@ -280,7 +280,7 @@ func (m *BoostService) handleGetHeader(w http.ResponseWriter, req *http.Request)
280280
url := relay.GetURI(path)
281281
log := log.WithField("url", url)
282282
responsePayload := new(types.GetHeaderResponse)
283-
code, err := SendHTTPRequest(context.Background(), m.httpClient, http.MethodGet, url, nil, responsePayload)
283+
code, err := SendHTTPRequest(context.Background(), m.httpClient, http.MethodGet, url, ua, nil, responsePayload)
284284
if err != nil {
285285
log.WithError(err).Warn("error making request to relay")
286286
return
@@ -365,6 +365,7 @@ func (m *BoostService) handleGetPayload(w http.ResponseWriter, req *http.Request
365365
defer requestCtxCancel()
366366
var wg sync.WaitGroup
367367
var mu sync.Mutex
368+
ua := UserAgent(req.Header.Get("User-Agent"))
368369

369370
for _, relay := range m.relays {
370371
wg.Add(1)
@@ -375,7 +376,7 @@ func (m *BoostService) handleGetPayload(w http.ResponseWriter, req *http.Request
375376
log.Debug("calling getPayload")
376377

377378
responsePayload := new(types.GetPayloadResponse)
378-
_, err := SendHTTPRequest(requestCtx, m.httpClient, http.MethodPost, url, payload, responsePayload)
379+
_, err := SendHTTPRequest(requestCtx, m.httpClient, http.MethodPost, url, ua, payload, responsePayload)
379380

380381
if err != nil {
381382
log.WithError(err).Warn("error making request to relay")
@@ -432,7 +433,7 @@ func (m *BoostService) CheckRelays() bool {
432433
m.log.WithField("relay", relay).Info("Checking relay")
433434

434435
url := relay.GetURI(pathStatus)
435-
_, err := SendHTTPRequest(context.Background(), m.httpClient, http.MethodGet, url, nil, nil)
436+
_, err := SendHTTPRequest(context.Background(), m.httpClient, http.MethodGet, url, "", nil, nil)
436437
if err != nil {
437438
m.log.WithError(err).WithField("relay", relay).Error("relay check failed")
438439
return false

server/service_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ func TestWebserverMaxHeaderSize(t *testing.T) {
129129
}()
130130
time.Sleep(time.Millisecond * 100)
131131
path := "http://" + addr + "?" + strings.Repeat("abc", 4000) // path with characters of size over 4kb
132-
code, err := SendHTTPRequest(context.Background(), *http.DefaultClient, http.MethodGet, path, nil, nil)
132+
code, err := SendHTTPRequest(context.Background(), *http.DefaultClient, http.MethodGet, path, "test", nil, nil)
133133
require.Error(t, err)
134134
require.Equal(t, http.StatusRequestHeaderFieldsTooLarge, code)
135135
backend.boost.srv.Close()

server/utils.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@ import (
88
"fmt"
99
"io"
1010
"net/http"
11+
"strings"
1112

1213
"github.com/ethereum/go-ethereum/common"
1314
"github.com/ethereum/go-ethereum/common/hexutil"
1415
"github.com/flashbots/go-boost-utils/types"
1516
)
1617

18+
// UserAgent is a custom string type to avoid confusing url + userAgent parameters in SendHTTPRequest
19+
type UserAgent string
20+
1721
// SendHTTPRequest - prepare and send HTTP request, marshaling the payload if any, and decoding the response if dst is set
18-
func SendHTTPRequest(ctx context.Context, client http.Client, method, url string, payload any, dst any) (code int, err error) {
22+
func SendHTTPRequest(ctx context.Context, client http.Client, method, url string, userAgent UserAgent, payload any, dst any) (code int, err error) {
1923
var req *http.Request
2024

2125
if payload == nil {
@@ -26,12 +30,18 @@ func SendHTTPRequest(ctx context.Context, client http.Client, method, url string
2630
return 0, fmt.Errorf("could not marshal request: %w", err2)
2731
}
2832
req, err = http.NewRequestWithContext(ctx, method, url, bytes.NewReader(payloadBytes))
33+
34+
// Set content-type
35+
req.Header.Add("Content-Type", "application/json")
2936
}
3037
if err != nil {
3138
return 0, fmt.Errorf("could not prepare request: %w", err)
3239
}
3340

34-
req.Header.Add("Content-Type", "application/json")
41+
// Set user agent
42+
req.Header.Set("User-Agent", strings.TrimSpace(fmt.Sprintf("mev-boost/%s %s", Version, userAgent)))
43+
44+
// Execute request
3545
resp, err := client.Do(req)
3646
if err != nil {
3747
return 0, err

server/utils_test.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"net/http"
7+
"net/http/httptest"
78
"testing"
89

910
"github.com/stretchr/testify/require"
@@ -12,7 +13,7 @@ import (
1213
func TestMakePostRequest(t *testing.T) {
1314
// Test errors
1415
var x chan bool
15-
code, err := SendHTTPRequest(context.Background(), *http.DefaultClient, http.MethodGet, "", x, nil)
16+
code, err := SendHTTPRequest(context.Background(), *http.DefaultClient, http.MethodGet, "", "test", x, nil)
1617
require.Error(t, err)
1718
require.Equal(t, 0, code)
1819
}
@@ -28,3 +29,30 @@ func TestDecodeJSON(t *testing.T) {
2829
require.Error(t, err)
2930
require.Equal(t, "json: unknown field \"c\"", err.Error())
3031
}
32+
33+
func TestSendHTTPRequestUserAgent(t *testing.T) {
34+
done := make(chan bool, 1)
35+
36+
// Test with custom UA
37+
customUA := "test-user-agent"
38+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
39+
require.Equal(t, "mev-boost/dev "+customUA, r.Header.Get("User-Agent"))
40+
done <- true
41+
}))
42+
defer ts.Close()
43+
code, err := SendHTTPRequest(context.Background(), *http.DefaultClient, http.MethodGet, ts.URL, UserAgent(customUA), nil, nil)
44+
require.NoError(t, err)
45+
require.Equal(t, 200, code)
46+
<-done
47+
48+
// Test without custom UA
49+
ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
50+
require.Equal(t, "mev-boost/dev", r.Header.Get("User-Agent"))
51+
done <- true
52+
}))
53+
defer ts.Close()
54+
code, err = SendHTTPRequest(context.Background(), *http.DefaultClient, http.MethodGet, ts.URL, "", nil, nil)
55+
require.NoError(t, err)
56+
require.Equal(t, 200, code)
57+
<-done
58+
}

0 commit comments

Comments
 (0)