Skip to content

Instrument payment phases and simplify shared chain paths - #43

Open
j0sh wants to merge 1 commit into
ja-codex/payment-33-cached-collateralfrom
ja-codex/payment-36-performance-metrics
Open

j0sh wants to merge 1 commit into
ja-codex/payment-33-cached-collateralfrom
ja-codex/payment-36-performance-metrics

Conversation

@j0sh

@j0sh j0sh commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Depends on #42. Merge after that PR.

Adds payment-phase duration histograms, fixed-allowlist contract-call counts, and foreground/background RPC accounting. Existing public metric names and label sets remain compatible. Observer health, observation age, head/L1 progress and partial payer failures come from memory; scrapes make no RPC calls.

Removes redundant chain/address adapters and duplicate observer flags, and reuses shared startup and paid-request fixtures. The concrete payment chain implements the existing interfaces directly. Cancellation remains serialized with cold-read admission before shutdown joins readers.

Focused regression tests run in normal CI. They enforce four foreground RPCs for a cold cached payment and zero for warm requests, alongside the direct-read budget, RPC failures, stale observations, canonical history, reorg, cancellation and settlement checks.

Production metrics support diagnosis and external measurement. End-to-end performance, deployment/provider comparisons and load scaling are measured through livepeer/e2e-runner.

Validation: affected package race suites (eth, internal/observability, orchestrator, signer) and diff/format checks passed. Source attribution is retained.

Closes #36.

@j0sh j0sh changed the title Measure payment performance and simplify shared chain paths Instrument payment phases and simplify shared chain paths Nov 3, 2026
@j0sh
j0sh force-pushed the ja-codex/payment-36-performance-metrics branch from 025f316 to eb1f8fd Compare November 4, 2026 00:03
@j0sh
j0sh force-pushed the ja-codex/payment-33-cached-collateral branch from de98232 to 0f1c07b Compare November 4, 2026 00:03
Instrument payment phases and authoritative RPC work. Consolidate
shared chain paths and RPC fixtures, retain CI regressions, and remove
the local payment benchmarks and historical comparison harness.
@j0sh
j0sh force-pushed the ja-codex/payment-33-cached-collateral branch from 0f1c07b to 6539bca Compare November 4, 2026 00:21
@j0sh
j0sh force-pushed the ja-codex/payment-36-performance-metrics branch from eb1f8fd to 15c6057 Compare November 4, 2026 00:21
@j0sh

j0sh commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator Author

Completed the requested end-to-end payment-path comparison against the combined stack, using builder issue #89 as the reference.

Performance-test implementation and reproduction harness: livepeer/e2e-runner#3.

Revision scope: these measurements and pass/fail outcomes are for combined commit 8b278e912b0aafb85a0851e439c4dae8cc5adbca. PR #43 is now at 15c605796be686a0393287afa43e285620f0158e. An exact file-tree comparison found six changed files, limited to documentation, tests, and a test helper; runtime files and dependency manifests are unchanged. The newer commit was not independently rerun.

At 110 ms additional latency per JSON-RPC HTTP exchange, the combined stack reduced median serial dispatch from 3,248.753 ms to 2.619 ms (99.9194%). Its warm latency was slightly higher than PR #1, and go-livepeer remained faster at 32 clients. The combined stack passed the shared cache-correctness cases that failed on PR #1.

Implementation 1 client: p50 / p95 ms 32 clients: p50 / p95 / p99 ms Warm successes across all conditions
Node baseline 3248.753 / 3252.021 3254.750 / 3269.131 / 3278.408 6,912/6,912 (100.000%)
BlueClaw PR #1 2.357 / 2.736 15.947 / 24.780 / 28.920 6,912/6,912 (100.000%)
Combined stack 2.619 / 3.156 16.792 / 25.283 / 29.954 6,912/6,912 (100.000%)
go-livepeer 2.525 / 3.000 9.851 / 16.721 / 21.230 6,906/6,912 (99.913%)

The six go-livepeer warm failures were paid-request HTTP 409 session already exists responses: one at 0 ms/32 clients and five at 110 ms/32 clients. Failed requests remain in attempted counts and reduce goodput. Latency quantiles use successful requests.

The test ran matched signer/orchestrator pairs on one GCP n2-standard-8 VM in us-west1-b, with Go 1.27.3 embedded in all measured binaries, native Anvil v1.9.0 finality/canonical reads, and protocol commit 3c01f3a3e8c494ea2f89b77d03eb0a68a4e15518. The protocol unlock period was two rounds for bounded withdrawal tests. Each request performed unpaid challenge → remote signing → paid forwarding to a minimal echo runner; the echoed request ID and runner arrival time were checked. These measurements exclude GPU inference and Internet gateway latency.

Pinned comparison inputs:

There were 48 final cells and 27,648 attempted warm jobs: three repetitions at 0/110 ms added RPC delay and 1/32 clients, with 128/1,024 jobs per repetition respectively. Each cell used fresh worker processes, payer, and databases, sharing one already-active recipient. Eight warmup jobs preceded measured load; explicit readiness retries were retained as warmup records. Timing targeted approximately 10,000,000 wei ticket EV and one ticket per job. Actual ticket parameters were decoded and retained; go-livepeer selected a different face value/winning probability with the same approximate EV. JSON-RPC batches retained their original bodies and incurred one delay per HTTP exchange.

All latency distributions and observed goodput
Added RPC delay Clients Implementation p50 / p95 / p99 dispatch, ms Successes / attempts Success rate Successes/s
0 ms 1 Node baseline 26.548 / 29.436 / — 384/384 100.000% 36.92
0 ms 1 BlueClaw PR #1 2.461 / 2.826 / — 384/384 100.000% 352.16
0 ms 1 Combined stack 2.630 / 3.114 / — 384/384 100.000% 326.54
0 ms 1 go-livepeer 2.562 / 3.245 / — 384/384 100.000% 336.87
0 ms 32 Node baseline 143.509 / 177.134 / 192.908 3,072/3,072 100.000% 218.56
0 ms 32 BlueClaw PR #1 16.171 / 24.923 / 28.811 3,072/3,072 100.000% 1900.46
0 ms 32 Combined stack 16.946 / 26.121 / 30.256 3,072/3,072 100.000% 1815.55
0 ms 32 go-livepeer 10.364 / 17.016 / 20.382 3,071/3,072 99.967% 2639.82
110 ms 1 Node baseline 3248.753 / 3252.021 / — 384/384 100.000% 0.31
110 ms 1 BlueClaw PR #1 2.357 / 2.736 / — 384/384 100.000% 364.96
110 ms 1 Combined stack 2.619 / 3.156 / — 384/384 100.000% 323.81
110 ms 1 go-livepeer 2.525 / 3.000 / — 384/384 100.000% 342.97
110 ms 32 Node baseline 3254.750 / 3269.131 / 3278.408 3,072/3,072 100.000% 9.82
110 ms 32 BlueClaw PR #1 15.947 / 24.780 / 28.920 3,072/3,072 100.000% 1918.79
110 ms 32 Combined stack 16.792 / 25.283 / 29.954 3,072/3,072 100.000% 1827.17
110 ms 32 go-livepeer 9.851 / 16.721 / 21.230 3,067/3,072 99.837% 2745.95

Quantiles are pooled across the three repetitions. Serial p99 is omitted because only 384 successes are available per condition; concurrent conditions have at least 3,067. These are finite closed-loop bursts. The cached paths finish quickly, so the goodput figures do not establish sustained saturation capacity. Ratios are observed differences, without statistical confidence bounds.

Immediate first-job probes are separate from warm results. The combined stack succeeded on 10/12 (83.3%), with two signer HTTP 400 payer funds unavailable rejections immediately after HTTP readiness; the other three variants succeeded on 12/12. These are small startup samples, not estimates of production failure probability. HTTP readiness does not guarantee payment readiness. Startup RPCs used the local provider before delay injection, and the first serial repetition included a 60-second pre-job idle window.

At 110 ms, median successful first-job dispatch for the serial condition was 455.163 ms combined, 230.778 ms PR #1, 228.656 ms go-livepeer, and 3,255.484 ms baseline Node. The controlled payment-read sequence used four cold exchanges combined versus two batched exchanges for PR #1; both used zero warm exchanges, versus 29 warm exchanges for baseline Node. The cold failures were retained and were not substituted with successful warm requests.

The real-chain and shared controlled correctness outcomes were:

Node implementation Protocol leaf cases Recovery cases Shared controlled leaf scenarios Full repository race suite
Baseline 38/38 (100%) 6/6 (100%) 13/13 (100%)* PASS
PR #1 38/38 (100%) 6/6 (100%) 10/13 (76.9%); 3 fail PASS
Combined 8b278e9 38/38 (100%) 6/6 (100%) 13/13 (100%) PASS

The frozen-head age requirement is asserted for cached implementations. The direct baseline performs fresh RPC reads and has no equivalent cache-age promise.

PR #1 failed the same additional, test-only scenarios against the shared provider fixture:

  • TestComparisonFrozenHead: repeated contact with an unchanged head made cached observations remain usable beyond the configured age.
  • TestComparisonKnownReorgFailedBackfill: after a known reorg and failed replacement observation, old collateral remained usable.
  • TestComparisonInFlightCancellation: canceling the last waiter returned to the caller but left provider work running past the 200 ms probe budget.

The combined stack rejected the stale/orphaned observations and canceled provider work. Other shared cases covered funding/current-round/registry changes, payer failure isolation, pre-cancellation, concurrent cold reads, and payer populations of 0/16/128/1,024. In the 32-distinct-key cold burst, combined provider concurrency was bounded at four, with 28/32 requests rejected while warm cached reads remained available. This is an admission-control tradeoff, separate from the all-successful warm load.

Recovery covered expired parameters, actual redemption and duplicate rejection, persisted pending tickets across restart, RPC interruption, delayed finality, and reorg recovery. The fixtures used genuine held finalized headers, canonical EIP-1898 reads, and actual snapshot/revert. Preparation allowed a bounded 20-second wait for funded-payer visibility before scenario faults; strict post-expiry rejection remained in place. Canonical replay was distinguished by exact transaction hash from the original already-public transaction: its original receipt still had to follow expiry, every settlement receipt had to match the canonical block hash, and canonical escrow was debited once. Superseded setup/assertion failures and subsequent reruns were retained.

A separate race-detector probe against the unchanged go-livepeer manifest-ID generator, in an isolated pinned source export with 32 callers, found a data race in common/util.go:324 and 200 duplicate IDs in 32,768 generations. This is consistent with the measured 409 reservation conflicts; the timing records do not establish a one-to-one causal trace for each conflict. Only the Node variants received the full protocol/recovery/repository-race comparison above.

Quiet-head refresh costs from the controlled provider test show the scaling tradeoff. Each entry is HTTP exchanges / contained JSON-RPC calls per refresh:

Tracked payers Combined PR #1
0 10 / 10 2 / 7
16 10 / 10 2 / 39
128 10 / 10 4 / 263
1,024 10 / 10 22 / 2,055

These quiet-history costs do not imply constant work when every payer changes on-chain. Whole-worker idle traffic also remains nonzero: under this harness at 110 ms after known-payer load, combined emitted approximately 19.18 contained RPC calls/s, versus 17.40 PR #1, 17.93 baseline Node, and 1.57 go-livepeer, counting both workers. Load-window RPC totals include background polling/redemption traffic and are not exact foreground counts.

Worker resource statistics at 110 ms and 32 clients
Implementation CPU ms / attempted job Orchestrator / signer sampled peak RSS, MiB
Node baseline 16.969 479.3 / 540.9
BlueClaw PR #1 2.279 370.6 / 331.9
Combined stack 2.409 371.8 / 332.4
go-livepeer 1.891 410.6 / 371.7

CPU comes from worker process counters and excludes setup, the load generator, and Anvil. RSS was sampled every 100 ms; the table takes the maximum sampled peak across repetitions.

Interpretation limits: the final reviewed combined revision was measured after the frozen baseline matrix on the same VM, so small differences between cached implementations can include ordering effects. The local chain mined at one-second intervals; production execution-block cadence, large history gaps, event-heavy histories, and Internet latency can alter results. This tests application behavior rather than production consensus safety. Test-only overlays did not alter the product checkouts.

The raw JSONL requests/RPC logs, per-cell metadata, source/binary hashes, fixture overlays, and reproduction harness are retained with the run artifacts. The temporary VM and boot disk were deleted and independently verified absent.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant