Skip to content

fix(solana): keep video settlement blockhash fresh via proactive re-sign#22

Merged
VickyXAI merged 2 commits into
BlockRunAI:mainfrom
KillerQueen-Z:fix/solana-video-fresh-blockhash
Jul 8, 2026
Merged

fix(solana): keep video settlement blockhash fresh via proactive re-sign#22
VickyXAI merged 2 commits into
BlockRunAI:mainfrom
KillerQueen-Z:fix/solana-video-fresh-blockhash

Conversation

@KillerQueen-Z

Copy link
Copy Markdown
Contributor

Problem

Customer hit transaction_simulation_failed (402) calling bytedance/seedance-2.0 at 1080p through the sidecar. Reproduced 2/2 with the released SDK (1.5.0).

Root cause (traced): the gateway settles the x402 payment only on a poll where the upstream status is completed. Slow / flaky-status video models (1080p Seedance Pro) bounce the upstream status completed <-> in_progress for minutes. The payment transaction is built + signed client-side with a Solana recent_blockhash (lifetime ~60-90s). By the time a settling completed poll lands, the signature is stale → transaction_simulation_failed. The existing on-402 re-sign can't outrun it: each re-signed blockhash re-expires during the next ~40s in_progress gap, and MEDIA_POLL_MAX_RESIGNS exhausts.

(Durable nonce would be the protocol-level cure, but the blockhash is set inside the third-party x402[svm] client — that's a client+facilitator+library change, out of scope here.)

Fix

During the async media poll loop, proactively re-sign the ORIGINAL challenge (identical amount/pay_to, freshly-fetched blockhash) every MEDIA_RESIGN_FRESH_SECONDS (25s), so the settlement signature is always fresh whenever upstream flips to completed.

  • Gated on max_resigns > 0video only; image path untouched.
  • Only the completed poll settles; in_progress polls ignore the header → never double-charges.
  • Best-effort: a failed proactive re-sign keeps the prior signature (pre-fix behaviour).
  • Applied to both SolanaLLMClient and AsyncSolanaLLMClient.

Validation

Live on Solana mainnet, the exact customer request (bytedance/seedance-2.0, 1080p, 5s, 16:9):

  • Before: 3 settlement-402s, re-signs exhausted, FAILED (2/2).
  • After: settles on the first completed poll, 0 settlement-402s, real mp4 delivered, on-chain tx 64fDCvbE…, $1.674918 settled once.

Regression: 114 passed (solana/image/cache/video), black clean.

Slow / flaky-status video models (1080p bytedance/seedance-2.0) bounce the
upstream status completed<->in_progress for minutes. The gateway settles only
on a 'completed' poll, so a signature made earlier goes stale (Solana blockhash
lifetime ~60-90s) before the settling poll lands — yielding a perpetual
transaction_simulation_failed that the on-402 re-sign can't outrun (each
re-signed blockhash re-expires during the next ~40s in_progress gap).

Fix: during the async media poll loop, proactively re-sign the ORIGINAL
challenge (same amount/pay_to, freshly-fetched blockhash) every
MEDIA_RESIGN_FRESH_SECONDS (25s) so the settlement signature is always fresh
whenever upstream flips to completed. Only the completed poll settles;
in-progress polls ignore the header, so this never double-charges. Best-effort:
a failed re-sign keeps the prior signature. Gated on max_resigns>0 (video only;
image unaffected).

Verified live on Solana mainnet: bytedance/seedance-2.0 at 1080p — the exact
customer request that failed 2/2 before — now settles on the first completed
poll with ZERO settlement-402s (tx 64fDCvbE…, $1.674918).
@KillerQueen-Z KillerQueen-Z force-pushed the fix/solana-video-fresh-blockhash branch from ea1d494 to aabb9d5 Compare July 8, 2026 01:24
…ign comment

- Add sync+async tests asserting max_resigns==0 (image path) never proactively
  re-signs even with a 0s freshness window — every poll reuses the single
  submit-time signature, proving the video-only fix leaves the image flow
  untouched.
- Reword the proactive re-sign comment (sync + async): 'async media path' ->
  'poll-based media path' to avoid confusion with the asyncio client.
@VickyXAI VickyXAI merged commit c3a32cb into BlockRunAI:main Jul 8, 2026
3 checks passed
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.

2 participants