Skip to content
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
23 changes: 23 additions & 0 deletions proxy/receiver_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
_ "embed"
"errors"
"log/slog"
"net/http"
"time"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -70,12 +71,34 @@ func (prx *ReceiverProxy) UserJSONRPCHandler(maxRequestBodySizeBytes int64) (*rp
Log: prx.Log,
MaxRequestBodySizeBytes: maxRequestBodySizeBytes,
VerifyRequestSignatureFromHeader: true,
ReadyHandler: prx.readyHandler,
},
)

return handler, err
}

// readyHandler calls /readyz on rbuilder
func (prx *ReceiverProxy) readyHandler(w http.ResponseWriter, r *http.Request) error {
resp, err := http.Get(prx.localBuilderEndpoint + "/readyz")
if err != nil {
prx.Log.Warn("Failed to check builder readiness", slog.Any("error", err))
http.Error(w, "not ready", http.StatusServiceUnavailable)
return nil
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
http.Error(w, "not ready", http.StatusServiceUnavailable)
return nil
}

// If the builder is ready, return 200 OK
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("ready"))
return nil
}

func (prx *ReceiverProxy) ValidateSigner(ctx context.Context, req *ParsedRequest, systemEndpoint bool) error {
req.signer = rpcserver.GetSigner(ctx)
if !systemEndpoint {
Expand Down
4 changes: 3 additions & 1 deletion proxy/receiver_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ type ReceiverProxy struct {

OrderflowSigner *signature.Signer

localBuilder rpcclient.RPCClient
localBuilder rpcclient.RPCClient
localBuilderEndpoint string

UserHandler http.Handler
SystemHandler http.Handler
Expand Down Expand Up @@ -108,6 +109,7 @@ func NewReceiverProxy(config ReceiverProxyConfig) (*ReceiverProxy, error) {
ConfigHub: NewBuilderConfigHub(config.Log, config.BuilderConfigHubEndpoint),
OrderflowSigner: orderflowSigner,
localBuilder: localBuilder,
localBuilderEndpoint: config.LocalBuilderEndpoint,
requestUniqueKeysRLU: expirable.NewLRU[uuid.UUID, struct{}](requestsRLUSize, nil, requestsRLUTTL),
replacementNonceRLU: expirable.NewLRU[replacementNonceKey, int](replacementNonceSize, nil, replacementNonceTTL),
userAPIRateLimiter: userAPIRateLimiter,
Expand Down
17 changes: 17 additions & 0 deletions proxy/receiver_proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -636,3 +636,20 @@ func TestValidateLocalBundles(t *testing.T) {

proxiesFlushQueue()
}

func TestJSONRPCServerReadyzOK(t *testing.T) {
tempDir := t.TempDir()
certPath := path.Join(tempDir, "cert")
keyPath := path.Join(tempDir, "key")
proxy, err := StartTestOrderflowProxy("1", certPath, keyPath)
require.NoError(t, err)

req := httptest.NewRequest(http.MethodGet, "/readyz", nil)

rr := httptest.NewRecorder()
proxy.localServer.Handler.ServeHTTP(rr, req)
respBody, err := io.ReadAll(rr.Body)
require.NoError(t, err)
require.Equal(t, http.StatusOK, rr.Code)
require.Contains(t, string(respBody), "ready")
}