Skip to content

feat(#50): prefetch-on-send (UN-DEPLOYED — needs supervised bridge-off verify)#52

Closed
Reiers wants to merge 2 commits into
mainfrom
feat/50-prefetch-on-send
Closed

feat(#50): prefetch-on-send (UN-DEPLOYED — needs supervised bridge-off verify)#52
Reiers wants to merge 2 commits into
mainfrom
feat/50-prefetch-on-send

Conversation

@Reiers

@Reiers Reiers commented Jun 21, 2026

Copy link
Copy Markdown
Owner

What

Closes the last residual on #50: a freshly-produced message block is not reliably served by random gossip peers within the client's receipt-poll window, so bridge-off the receipt lookup occasionally fails with net/bitswap: context canceled.

This implements #50 fix-option 2 (prefetch-on-send): when eth_sendRawTransaction publishes a tx locally, we start a background StateSearchMsg poll for its message CID on a standalone, generous-deadline context. That background search drives the embedded Bitswap source to pull the message + AMT + receipt blocks into cache as soon as the tx lands — so the client's own short-deadline receipt poll hits a warm cache instead of racing a cold cross-peer fetch.

How

  • New ChainAPI.OnSentTx hook, fired non-blocking after a successful local MpoolPush (mirrors the Embedded state-block availability for local eth_call (last blocker for --vm-bridge-rpc-disable) #44 OnLocalMiss adaptive-warming pattern).
  • pkg/daemon sendWarmer: per-tx background warm loop with dedup, a concurrency cap (64), self-bounding (stop on found / 10-minute max), bound to the daemon root context (cancelled on Stop).
  • Purely additive and read-only: a nil hook = unchanged behavior; it never affects the send result; it never publishes or mutates state.

Tests

  • 5 unit tests (stop-on-found, dedup, concurrency cap, context-cancel, nil-safe), green under -race.
  • Full pkg/daemon + rpc/handlers suites green.
  • Build + go vet clean, CGO_ENABLED=0.

⚠️ DO NOT MERGE YET — needs live verification

The engine builds and unit-tests clean, but the real proof is a bridge-off write-confirm cycle on cc-smoke showing zero net/bitswap: context canceled receipt misses across several sends. That is a supervised, daytime, bridge-off test (per ops policy — bridge-off proving tests are not run unsupervised).

This PR is intentionally opened separate from / unrelated to the in-flight mainnet PDP first-proof window (that runs bridge-ON on Curio Core and has nothing to do with this Lantern bitswap path). Parking it here as code-complete so the daytime session is "deploy + watch", not "write from scratch".

Verification checklist (for the supervised session)

  • Build the branch binary, deploy to cc-smoke, keep VM bridge configured as the safety net initially.
  • Confirm eth_sendRawTransaction: published locally + a background warm kicks in (add a debug log if needed).
  • Flip bridge-off via the clean drop-in, run a real SP write-confirm cycle.
  • Confirm receipt resolves LOCAL with 0 net/bitswap: context canceled across N sends.
  • Roll back to bridge-ON between tests; only merge after a clean run.

…(UN-DEPLOYED, needs supervised bridge-off verify)

When eth_sendRawTransaction publishes a tx locally (#45 Stage 4), start a
background StateSearchMsg poll for its message CID on a standalone,
generous-deadline context. That background search drives the embedded
Bitswap source to pull the freshly-produced message + AMT + receipt blocks
into cache as soon as the tx lands. By the time the client's own short-
deadline receipt poll runs, the blocks are warm and the receipt resolves
locally instead of racing (and losing to) a cold cross-peer Bitswap fetch
inside the poll window — the residual that kept #50 open.

- new ChainAPI.OnSentTx hook, fired non-blocking after a successful local
  MpoolPush (mirrors the #44 OnLocalMiss adaptive-warming pattern)
- pkg/daemon sendWarmer: per-tx background warm loop, dedup, concurrency
  cap (64), self-bounded (stop on found / 10m max), bound to daemon root ctx
- purely additive + read-only: nil hook = unchanged behavior; never affects
  the send result; never publishes or mutates state
- 5 unit tests (stop-on-found, dedup, concurrency cap, ctx-cancel, nil-safe),
  pass under -race; full pkg/daemon + rpc/handlers suites green

NOT deployed to cc-smoke. Needs live bridge-off verification in a supervised
daytime window before merge (the engine builds + unit-tests clean, but the
real proof is a bridge-off write-confirm cycle showing zero
'net/bitswap: context canceled' receipt misses).
Formatting-only; no behavioral change. The branch CI failed on gofmt drift
(struct field alignment in sendWarmer). No logic touched.
Reiers added a commit that referenced this pull request Jun 30, 2026
Part 3 of #50. The embedded daemon hardcoded Glif as the polling Sync head
source + cold-block fallback with no opt-out, so a bridge-off node silently
fell back to Glif whenever gossip stalled - a hidden third-party dependency.

- Config.FallbackRPC overrides the upstream RPC URL (e.g. operator's own
  Forest), defaulting to the network Glif URL (unchanged behavior).
- Config.NoFallbackRPC removes the upstream RPC entirely: head comes only
  from gossipsub, cold blocks only from gateway+Bitswap. A gossip stall then
  surfaces as a stalled head (observable) instead of a silent Glif fetch.
  Refuses to start if libp2p is disabled (no head source at all).

Wired so syncSrc/backfillSrc are truly-nil interfaces (not typed-nil) when
NoFallbackRPC, and hstore.Sync.pollAndApply guards nil src as a no-op so
gossip drives the head alone without nil-panicking. Test: nil-source Sync is
a safe no-op leaving head intact.

(Part 1 = PR #52 prefetch-on-send, merged. Part 2 = msgsearch
bitswap-with-retry, already shipped in the #77 bridge-off parity work.)
@Reiers

Reiers commented Jun 30, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #84 — the prefetch-on-send commits were merged into the v1.8.5 release branch (fix/83-lag-aware-gossip-skip) along with the rest of #50. Closing in favor of #84.

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