diff --git a/harnesses/indexing-freshness/Dockerfile b/harnesses/indexing-freshness/Dockerfile deleted file mode 100644 index 63108cfc..00000000 --- a/harnesses/indexing-freshness/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -FROM golang:1.24-alpine AS builder - -WORKDIR /app -RUN apk add --no-cache git - -COPY go.mod go.sum ./ -RUN go mod download - -COPY . . - -RUN CGO_ENABLED=0 GOOS=linux go build -o /app/monitor ./cmd/script - -FROM debian:bookworm-slim - -WORKDIR /app -RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/* - -COPY --from=builder /app/monitor /app/monitor - -EXPOSE 2112 - -CMD ["/app/monitor"] diff --git a/harnesses/indexing-freshness/cmd/script/config.go b/harnesses/indexing-freshness/cmd/script/config.go deleted file mode 100644 index b4d86824..00000000 --- a/harnesses/indexing-freshness/cmd/script/config.go +++ /dev/null @@ -1,67 +0,0 @@ -package main - -import ( - "os" - "strconv" - "strings" - "time" -) - -// Provider is one wallet-data API we race. Keys come exclusively from -// env (INDEXING_KEY_); a provider without a key is skipped. -// -// EveryN throttles participation for quota-tight free tiers: the -// provider only joins every Nth probe event. Budget is the monthly -// API-call budget for the guard (90% cutoff, calendar-month reset) — -// derived from each free tier's documented quota with headroom. -type Provider struct { - Slug string - EveryN int - Budget int64 -} - -var providers = []Provider{ - {Slug: "mobula", EveryN: 1, Budget: 250_000}, - {Slug: "zerion", EveryN: 1, Budget: 55_000}, - {Slug: "goldrush", EveryN: 1, Budget: 90_000}, - // Allium free tier: 20k calls/month, aggressive per-second limits. - {Slug: "allium", EveryN: 3, Budget: 18_000}, -} - -func keyFor(slug string) string { - return strings.TrimSpace(os.Getenv("INDEXING_KEY_" + strings.ToUpper(slug))) -} - -func activeProviders() []Provider { - var out []Provider - for _, p := range providers { - if keyFor(p.Slug) != "" { - out = append(out, p) - } - } - return out -} - -const chainSlug = "base" - -func rpcHTTP() string { return strings.TrimSpace(os.Getenv("INDEXING_RPC_HTTP")) } -func rpcWSS() string { return strings.TrimSpace(os.Getenv("INDEXING_RPC_WSS")) } - -// eventInterval: one probe event (fresh organic tx picked from a new -// block) per interval. 10 min default → 144 events/day, which keeps -// every provider inside its monthly free quota given the poll schedule. -func eventInterval() time.Duration { - if v := strings.TrimSpace(os.Getenv("INDEXING_EVENT_SECONDS")); v != "" { - if n, err := strconv.Atoi(v); err == nil && n >= 60 { - return time.Duration(n) * time.Second - } - } - return 10 * time.Minute -} - -// pollSchedule: seconds after T0 at which each provider is polled. -// Front-loaded because the interesting race happens in the first -// seconds; capped at 120s after which the event counts as "missed". -// Precision note for the methodology: measured lag is an upper bound -// with resolution equal to the gap between consecutive polls. -var pollSchedule = []int{1, 2, 3, 4, 6, 8, 11, 15, 20, 26, 34, 45, 60, 80, 100, 120} diff --git a/harnesses/indexing-freshness/cmd/script/main.go b/harnesses/indexing-freshness/cmd/script/main.go deleted file mode 100644 index 5d2ab929..00000000 --- a/harnesses/indexing-freshness/cmd/script/main.go +++ /dev/null @@ -1,131 +0,0 @@ -package main - -import ( - "context" - "fmt" - "os" - "os/signal" - "strings" - "sync" - "syscall" - "time" -) - -// indexing-freshness — bench №070. -// -// One probe event per interval: grab a fresh organic native transfer -// from the newest block (T0 = our observation of the block), then poll -// every cohort wallet API on a front-loaded schedule until each one -// returns the tx (lag = poll time − T0) or 120s passes (missed). - -func main() { - fmt.Println("=== Indexing Freshness Harness ===") - fmt.Println("OpenChainBench — organic tx → wallet-API visibility lag.") - if rpcHTTP() == "" { - fmt.Println("[fatal] INDEXING_RPC_HTTP not set") - os.Exit(1) - } - active := activeProviders() - if len(active) == 0 { - fmt.Println("[fatal] no INDEXING_KEY_* env vars set") - os.Exit(1) - } - fmt.Printf("Chain: %s | event interval: %s | poll cap: %ds\n", chainSlug, eventInterval(), pollSchedule[len(pollSchedule)-1]) - for _, p := range active { - fmt.Printf(" - %-10s everyN=%d budget=%d calls/mo\n", p.Slug, p.EveryN, p.Budget) - } - - addr := ":2112" - if v := strings.TrimSpace(os.Getenv("METRICS_ADDR")); v != "" { - addr = v - } - fmt.Printf("Metrics server: %s/metrics\n\n", addr) - go func() { - if err := StartMetricsServer(addr); err != nil { - fmt.Printf("[fatal] metrics server: %v\n", err) - os.Exit(1) - } - }() - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - go runEvents(ctx, active) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, os.Interrupt, syscall.SIGTERM) - s := <-sig - fmt.Printf("\n[shutdown] %v\n", s) - cancel() -} - -func runEvents(ctx context.Context, active []Provider) { - t := time.NewTicker(eventInterval()) - defer t.Stop() - var lastSeen uint64 - eventN := 0 - for { - eventN++ - _, bn, tx := waitFreshBlock(lastSeen) - lastSeen = bn - t0 := time.Now() - fmt.Printf("[event %d] block=%d tx=%s wallet=%s\n", eventN, bn, tx.Hash[:14]+"…", tx.From[:10]+"…") - - var wg sync.WaitGroup - for _, p := range active { - if eventN%p.EveryN != 0 { - continue - } - if !quota.allow(p) { - probeTotal.WithLabelValues(p.Slug, chainSlug, "quota_paused").Inc() - fmt.Printf(" %-10s quota guard tripped — paused until month rollover\n", p.Slug) - continue - } - wg.Add(1) - go func(p Provider) { - defer wg.Done() - raceProvider(ctx, p, tx.From, tx.Hash, t0) - }(p) - } - wg.Wait() - - select { - case <-ctx.Done(): - return - case <-t.C: - } - } -} - -func raceProvider(ctx context.Context, p Provider, wallet, txHash string, t0 time.Time) { - var lastErr error - for _, after := range pollSchedule { - wait := time.Until(t0.Add(time.Duration(after) * time.Second)) - if wait > 0 { - select { - case <-ctx.Done(): - return - case <-time.After(wait): - } - } - found, err := checkProvider(p.Slug, wallet, txHash) - if err != nil { - lastErr = err - continue - } - if found { - lag := time.Since(t0).Seconds() - freshnessSeconds.WithLabelValues(p.Slug, chainSlug).Set(lag) - freshnessHist.WithLabelValues(p.Slug, chainSlug).Observe(lag) - probeTotal.WithLabelValues(p.Slug, chainSlug, "found").Inc() - fmt.Printf(" %-10s found in %.1fs\n", p.Slug, lag) - return - } - } - if lastErr != nil { - probeTotal.WithLabelValues(p.Slug, chainSlug, "api_error").Inc() - fmt.Printf(" %-10s api_error: %s\n", p.Slug, sanitize(lastErr)) - return - } - probeTotal.WithLabelValues(p.Slug, chainSlug, "missed").Inc() - fmt.Printf(" %-10s MISSED (not indexed within %ds)\n", p.Slug, pollSchedule[len(pollSchedule)-1]) -} diff --git a/harnesses/indexing-freshness/cmd/script/metrics.go b/harnesses/indexing-freshness/cmd/script/metrics.go deleted file mode 100644 index e2286884..00000000 --- a/harnesses/indexing-freshness/cmd/script/metrics.go +++ /dev/null @@ -1,62 +0,0 @@ -package main - -import ( - "net/http" - - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" - "github.com/prometheus/client_golang/prometheus/promhttp" -) - -var ( - freshnessSeconds = promauto.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "indexing_freshness_seconds", - Help: "Latest observed lag between an organic on-chain tx confirmation and the moment the provider's wallet API first returns it.", - }, - []string{"provider", "chain"}, - ) - - freshnessHist = promauto.NewHistogramVec( - prometheus.HistogramOpts{ - Name: "indexing_freshness_seconds_histogram", - Help: "Histogram of wallet-API indexing freshness lags — drives p50/p90 via quantile_over_time.", - Buckets: []float64{1, 2, 3, 4, 6, 8, 11, 15, 20, 26, 34, 45, 60, 80, 100, 120}, - }, - []string{"provider", "chain"}, - ) - - probeTotal = promauto.NewCounterVec( - prometheus.CounterOpts{ - Name: "indexing_probe_total", - Help: "Probe outcomes per provider: found | missed (not indexed within 120s) | api_error | quota_paused.", - }, - []string{"provider", "chain", "result"}, - ) - - apiCalls = promauto.NewCounterVec( - prometheus.CounterOpts{ - Name: "indexing_api_calls_total", - Help: "API calls issued per provider (feeds the monthly quota guard).", - }, - []string{"provider"}, - ) - - quotaUsedRatio = promauto.NewGaugeVec( - prometheus.GaugeOpts{ - Name: "indexing_quota_used_ratio", - Help: "Fraction of the provider's monthly call budget consumed (probing pauses at 0.90).", - }, - []string{"provider"}, - ) -) - -func StartMetricsServer(addr string) error { - mux := http.NewServeMux() - mux.Handle("/metrics", promhttp.Handler()) - mux.HandleFunc("/health", func(w http.ResponseWriter, _ *http.Request) { - w.WriteHeader(http.StatusOK) - _, _ = w.Write([]byte("ok")) - }) - return http.ListenAndServe(addr, mux) -} diff --git a/harnesses/indexing-freshness/cmd/script/pollers.go b/harnesses/indexing-freshness/cmd/script/pollers.go deleted file mode 100644 index de7b8463..00000000 --- a/harnesses/indexing-freshness/cmd/script/pollers.go +++ /dev/null @@ -1,111 +0,0 @@ -package main - -import ( - "bytes" - "encoding/base64" - "fmt" - "io" - "net/http" - "strings" - "sync" - "time" -) - -// Detection is deliberately parser-free: we lowercase the raw response -// body and look for the tx hash substring. Every cohort API returns the -// hash verbatim in its JSON, so this is immune to per-provider schema -// churn and cannot be accused of favouring any response shape. -func bodyContains(resp *http.Response, txHash string) (bool, error) { - defer resp.Body.Close() - raw, err := io.ReadAll(io.LimitReader(resp.Body, 4<<20)) - if err != nil { - return false, err - } - if resp.StatusCode != 200 { - return false, fmt.Errorf("status %d", resp.StatusCode) - } - return bytes.Contains(bytes.ToLower(raw), []byte(strings.ToLower(txHash))), nil -} - -var httpClient = &http.Client{Timeout: 8 * time.Second} - -// checkProvider asks one provider's wallet API whether it has indexed -// txHash for wallet yet. Returns (found, error). Every call increments -// the quota counter regardless of outcome. -func checkProvider(slug, wallet, txHash string) (bool, error) { - apiCalls.WithLabelValues(slug).Inc() - key := keyFor(slug) - var req *http.Request - var err error - - switch slug { - case "zerion": - u := fmt.Sprintf("https://api.zerion.io/v1/wallets/%s/transactions/?page%%5Bsize%%5D=20&filter%%5Bchain_ids%%5D=%s", wallet, chainSlug) - req, err = http.NewRequest("GET", u, nil) - if err == nil { - req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(key+":"))) - req.Header.Set("Accept", "application/json") - } - case "goldrush": - u := fmt.Sprintf("https://api.covalenthq.com/v1/%s-mainnet/address/%s/transactions_v3/?page-size=20", chainSlug, wallet) - req, err = http.NewRequest("GET", u, nil) - if err == nil { - req.Header.Set("Authorization", "Bearer "+key) - } - case "allium": - body := fmt.Sprintf(`[{"chain":"%s","address":"%s","limit":20}]`, chainSlug, wallet) - req, err = http.NewRequest("POST", "https://api.allium.so/api/v1/developer/wallet/transactions", strings.NewReader(body)) - if err == nil { - req.Header.Set("X-API-KEY", key) - req.Header.Set("Content-Type", "application/json") - } - case "mobula": - u := fmt.Sprintf("https://api.mobula.io/api/1/wallet/transactions?wallet=%s&limit=20", wallet) - req, err = http.NewRequest("GET", u, nil) - if err == nil { - req.Header.Set("Authorization", key) - } - default: - return false, fmt.Errorf("unknown provider %s", slug) - } - if err != nil { - return false, err - } - req.Header.Set("User-Agent", "OpenChainBench/1.0 (+https://openchainbench.com)") - resp, err := httpClient.Do(req) - if err != nil { - return false, err - } - return bodyContains(resp, txHash) -} - -// --------------------------------------------------------------------------- -// Monthly quota guard (same design as rpc-keyed-latency). -// --------------------------------------------------------------------------- - -type quotaGuard struct { - mu sync.Mutex - month string - counts map[string]int64 -} - -var quota = "aGuard{counts: make(map[string]int64)} - -func (q *quotaGuard) allow(p Provider) bool { - q.mu.Lock() - defer q.mu.Unlock() - m := time.Now().UTC().Format("2006-01") - if m != q.month { - q.month = m - q.counts = make(map[string]int64) - } - used := q.counts[p.Slug] - ratio := float64(used) / float64(p.Budget) - quotaUsedRatio.WithLabelValues(p.Slug).Set(ratio) - if ratio >= 0.90 { - return false - } - // Reserve the worst case for one event (full poll schedule). - q.counts[p.Slug] = used + int64(len(pollSchedule)) - return true -} diff --git a/harnesses/indexing-freshness/cmd/script/sampler.go b/harnesses/indexing-freshness/cmd/script/sampler.go deleted file mode 100644 index 33a2d2ee..00000000 --- a/harnesses/indexing-freshness/cmd/script/sampler.go +++ /dev/null @@ -1,139 +0,0 @@ -package main - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "math/rand" - "net/http" - "strconv" - "strings" - "time" -) - -// The organic sampler. Instead of funding a probe wallet, we pick a -// fresh native transfer from the newest block: real user, real tx, -// different wallet every event — which also makes the ground truth -// impossible for a provider to special-case (there is no benchmark -// wallet to whitelist). -// -// T0 = the instant WE observe the block containing the tx via our own -// RPC. Identical reference for every provider, same host clock. - -type rpcTx struct { - Hash string `json:"hash"` - From string `json:"from"` - To string `json:"to"` - Input string `json:"input"` - Value string `json:"value"` -} - -type rpcBlock struct { - Number string `json:"number"` - Transactions []rpcTx `json:"transactions"` -} - -func rpcCall(method string, params string) (json.RawMessage, error) { - body := fmt.Sprintf(`{"jsonrpc":"2.0","method":"%s","params":%s,"id":%d}`, method, params, time.Now().UnixNano()) - req, _ := http.NewRequest("POST", rpcHTTP(), strings.NewReader(body)) - req.Header.Set("Content-Type", "application/json") - req.Header.Set("User-Agent", "OpenChainBench/1.0 (+https://openchainbench.com)") - resp, err := httpClient.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - raw, err := io.ReadAll(io.LimitReader(resp.Body, 8<<20)) - if err != nil { - return nil, err - } - var env struct { - Result json.RawMessage `json:"result"` - Error *struct { - Message string `json:"message"` - } `json:"error"` - } - if err := json.Unmarshal(raw, &env); err != nil { - return nil, err - } - if env.Error != nil { - return nil, fmt.Errorf("rpc: %s", env.Error.Message) - } - return env.Result, nil -} - -func latestBlock() (*rpcBlock, error) { - res, err := rpcCall("eth_getBlockByNumber", `["latest",true]`) - if err != nil { - return nil, err - } - var b rpcBlock - if err := json.Unmarshal(res, &b); err != nil { - return nil, err - } - return &b, nil -} - -// pickNativeTransfer returns a random plain native transfer from the -// block: value > 0, empty calldata, sender is a normal EOA. On OP-stack -// chains transactions[0] is always the L1 system deposit — the -// 0xdeaddead filter drops it. -func pickNativeTransfer(b *rpcBlock) *rpcTx { - var cands []rpcTx - for _, tx := range b.Transactions { - if tx.Input != "0x" || tx.To == "" || strings.EqualFold(tx.From, tx.To) { - continue - } - if strings.HasPrefix(strings.ToLower(tx.From), "0xdeaddead") { - continue - } - v, err := strconv.ParseUint(strings.TrimPrefix(tx.Value, "0x"), 16, 64) - if err != nil || v == 0 { - continue - } - cands = append(cands, tx) - } - if len(cands) == 0 { - return nil - } - tx := cands[rand.Intn(len(cands))] - return &tx -} - -// waitFreshBlock polls the RPC until a block newer than lastSeen with a -// usable native transfer shows up. 500ms cadence bounds the T0 error at -// +500ms, identical for every provider. -func waitFreshBlock(lastSeen uint64) (*rpcBlock, uint64, *rpcTx) { - for { - b, err := latestBlock() - if err != nil { - time.Sleep(2 * time.Second) - continue - } - bn, _ := strconv.ParseUint(strings.TrimPrefix(b.Number, "0x"), 16, 64) - if bn > lastSeen { - if tx := pickNativeTransfer(b); tx != nil { - return b, bn, tx - } - lastSeen = bn - } - time.Sleep(500 * time.Millisecond) - } -} - -// sanitize strips anything URL-ish from provider errors before logging -// (defense in depth — no endpoint carries a key in this harness's URLs -// except mobula/allium headers, but keep the rule uniform). -func sanitize(err error) string { - if err == nil { - return "" - } - s := err.Error() - if i := strings.Index(s, "http"); i >= 0 { - return s[:i] + "" - } - return s -} - -var _ = bytes.MinRead diff --git a/harnesses/indexing-freshness/go.mod b/harnesses/indexing-freshness/go.mod deleted file mode 100644 index 55bd09f7..00000000 --- a/harnesses/indexing-freshness/go.mod +++ /dev/null @@ -1,18 +0,0 @@ -module indexing-freshness - -go 1.24.0 - -require github.com/prometheus/client_golang v1.23.2 - -require ( - github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/kr/text v0.2.0 // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/prometheus/client_model v0.6.2 // indirect - github.com/prometheus/common v0.66.1 // indirect - github.com/prometheus/procfs v0.16.1 // indirect - go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/sys v0.35.0 // indirect - google.golang.org/protobuf v1.36.8 // indirect -) diff --git a/harnesses/indexing-freshness/go.sum b/harnesses/indexing-freshness/go.sum deleted file mode 100644 index d6b8ca98..00000000 --- a/harnesses/indexing-freshness/go.sum +++ /dev/null @@ -1,46 +0,0 @@ -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= -github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= -github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= -github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= -github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= -github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= -go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= -go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/harnesses/indexing-freshness/railway.toml b/harnesses/indexing-freshness/railway.toml deleted file mode 100644 index 2abbb1f0..00000000 --- a/harnesses/indexing-freshness/railway.toml +++ /dev/null @@ -1,7 +0,0 @@ -[build] -builder = "DOCKERFILE" -dockerfilePath = "Dockerfile" - -[deploy] -healthcheckPath = "/health" -restartPolicyType = "ON_FAILURE"