From 78d1b541f21abce8170d896cf35579d8403ec810 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 28 Nov 2023 17:51:32 +0100 Subject: [PATCH] Handle error and integrate other external calls --- core/vm/contracts_suave.go | 15 ++++--- core/vm/contracts_suave_eth.go | 76 ++++++++++----------------------- core/vm/contracts_suave_test.go | 9 ++++ 3 files changed, 40 insertions(+), 60 deletions(-) diff --git a/core/vm/contracts_suave.go b/core/vm/contracts_suave.go index df55905492..669cf9c4da 100644 --- a/core/vm/contracts_suave.go +++ b/core/vm/contracts_suave.go @@ -6,6 +6,7 @@ import ( "io" "net/http" "strings" + "time" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" @@ -126,11 +127,6 @@ func mustParseMethodAbi(data string, method string) abi.Method { return inoutAbi.Methods[method] } -func formatPeekerError(format string, args ...any) ([]byte, error) { - err := fmt.Errorf(format, args...) - return []byte(err.Error()), err -} - type suaveRuntime struct { suaveContext *SuaveContext } @@ -163,7 +159,10 @@ func (s *suaveRuntime) doHTTPRequest(request types.HttpRequest) ([]byte, error) req.Header.Add(prts[0], prts[1]) } - resp, err := http.DefaultClient.Do(req) + client := &http.Client{ + Timeout: 5 * time.Second, // TODO: test + } + resp, err := client.Do(req) if err != nil { return nil, err } @@ -173,5 +172,9 @@ func (s *suaveRuntime) doHTTPRequest(request types.HttpRequest) ([]byte, error) if err != nil { return nil, err } + + if resp.StatusCode > 299 { + return nil, fmt.Errorf("http error: %s: %v", resp.Status, data) + } return data, nil } diff --git a/core/vm/contracts_suave_eth.go b/core/vm/contracts_suave_eth.go index 80e1c1f88f..bf513bc6b0 100644 --- a/core/vm/contracts_suave_eth.go +++ b/core/vm/contracts_suave_eth.go @@ -1,11 +1,9 @@ package vm import ( - "bytes" "context" "encoding/json" "fmt" - "io" "math/big" "net/http" "time" @@ -280,35 +278,19 @@ func (b *suaveRuntime) buildEthBlock(blockArgs types.BuildBlockArgs, bidId types } func (b *suaveRuntime) submitEthBlockBidToRelay(relayUrl string, builderBidJson []byte) ([]byte, error) { - ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(3*time.Second)) - defer cancel() - endpoint := relayUrl + "/relay/v1/builder/blocks" - req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, bytes.NewReader(builderBidJson)) - if err != nil { - return formatPeekerError("could not prepare request to relay: %w", err) - } - req.Header.Add("Content-Type", "application/json") - - // Execute request - resp, err := http.DefaultClient.Do(req) - if err != nil { - return formatPeekerError("could not send request to relay: %w", err) + httpReq := types.HttpRequest{ + Method: http.MethodPost, + Url: endpoint, + Body: builderBidJson, + Headers: []string{ + "Content-Type: application/json", + "Accept: application/json", + }, } - defer resp.Body.Close() - - if resp.StatusCode == http.StatusNoContent { - return nil, nil - } - - if resp.StatusCode > 299 { - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return formatPeekerError("could not read error response body for status code %d: %w", resp.StatusCode, err) - } - - return formatPeekerError("relay request failed with code %d: %s", resp.StatusCode, string(bodyBytes)) + if _, err := b.doHTTPRequest(httpReq); err != nil { + return nil, err } return nil, nil @@ -356,9 +338,6 @@ func executableDataToCapellaExecutionPayload(data *engine.ExecutableData) (*spec } func (c *suaveRuntime) submitBundleJsonRPC(url string, method string, params []byte) ([]byte, error) { - ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(3*time.Second)) - defer cancel() - request := map[string]interface{}{ "id": json.RawMessage([]byte("1")), "jsonrpc": "2.0", @@ -379,29 +358,18 @@ func (c *suaveRuntime) submitBundleJsonRPC(url string, method string, params []b signature := crypto.PubkeyToAddress(c.suaveContext.Backend.EthBundleSigningKey.PublicKey).Hex() + ":" + hexutil.Encode(sig) - req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewBuffer(body)) - if err != nil { - return formatPeekerError("could not prepare request to relay: %w", err) - } - - req.Header.Add("Content-Type", "application/json") - req.Header.Add("Accept", "application/json") - req.Header.Add("X-Flashbots-Signature", signature) - - // Execute request - resp, err := http.DefaultClient.Do(req) - if err != nil { - return formatPeekerError("could not send request to relay: %w", err) - } - defer resp.Body.Close() - - if resp.StatusCode > 299 { - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return formatPeekerError("request failed with code %d", resp.StatusCode) - } - - return formatPeekerError("request failed with code %d: %s", resp.StatusCode, string(bodyBytes)) + httpReq := types.HttpRequest{ + Method: http.MethodPost, + Url: url, + Body: body, + Headers: []string{ + "Content-Type: application/json", + "Accept: application/json", + "X-Flashbots-Signature: " + signature, + }, + } + if _, err := c.doHTTPRequest(httpReq); err != nil { + return nil, err } return nil, nil diff --git a/core/vm/contracts_suave_test.go b/core/vm/contracts_suave_test.go index 8d1c624e99..35c631f020 100644 --- a/core/vm/contracts_suave_test.go +++ b/core/vm/contracts_suave_test.go @@ -268,6 +268,10 @@ func (h *httpTestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Write([]byte(val)) return } + if val := r.Header.Get("fail"); val != "" { + w.WriteHeader(http.StatusInternalServerError) + return + } if r.Method == "POST" { w.Write([]byte("ok")) return @@ -321,6 +325,11 @@ func TestSuave_HttpRequest(t *testing.T) { req: types.HttpRequest{Url: srv.URL, Method: "POST", Headers: []string{"a:c"}}, resp: []byte("c"), }, + { + // POST with error + req: types.HttpRequest{Url: srv.URL, Method: "POST", Headers: []string{"fail:1"}}, + err: true, + }, } for _, c := range cases {