Skip to content

feat(bridge): batch withdraw/refund proposals (force_batch API + E2E harness)#1104

Draft
sameh-farouk wants to merge 1 commit into
developmentfrom
feat/bridge-batch-proposals
Draft

feat(bridge): batch withdraw/refund proposals (force_batch API + E2E harness)#1104
sameh-farouk wants to merge 1 commit into
developmentfrom
feat/bridge-batch-proposals

Conversation

@sameh-farouk
Copy link
Copy Markdown
Member

Summary

Clean, batching-focused extraction of the remaining unique work from the old #1079 draft, rebuilt on current development. Replaces #1079 (which is now ~95% merged or superseded — see below).

Contains the batching API layer (unwired) + the local E2E test harness. The handler integration is intentionally not included — it must be rebuilt on top of the per-tx idempotency work (#1096) when this is picked up.

What's here

Batching API

  • clients/tfchain-client-go/batch.goBatchCalls: N calls in one Utility.force_batch extrinsic (continues through per-item failures, unlike batch/batch_all).
  • pkg/substrate/client.goBurnProposal/RefundProposal + BatchProposeAll (batched propose) and BatchSetWithdrawExecuted/BatchSetRefundTransactionExecuted (batched confirm), each with single-item + whole-batch fallback to the existing Retry* paths.
  • pkg/substrate/events.go — populate the already-declared RefundCreatedEvents.

Local E2E test harness

  • scripts/bridge_*.js + wait_for_node.js — single- and multi-validator (2-of-3) E2E scenarios incl. crash recovery, double-spend, backlog drain.
  • Makefilebridge-dev / bridge-test / bridge-mv-* targets.
  • bridge/docs/local_development_setup.md.

⚠️ Known follow-ups before production-ready (from the #1079 review)

  1. force_batch ItemFailed carries no call index — re-derive true per-item outcomes (IsBurnedAlready / signature presence) instead of trusting the aggregate count, or switch to Utility.batch + BatchInterrupted.Index.
  2. Failure count is whole-block, phase-unfiltered — filter Utility_ItemFailed by the batch extrinsic's phase (mirror checkForError) and clamp SuccessCount.
  3. No size cap — chunk calls into bounded sub-batches (avoid the block-weight cliff on backlog drain).
  4. Wire the handler integration on feat(bridge): crash-safe idempotency for withdraws and refunds #1096's per-tx submit, and add Go unit tests for BatchCalls / the proposal mapping.

Why a new PR instead of trimming #1079

#1079 was 49 ahead / 20 behind and CONFLICTING; its fixes are merged (#1094/#1095/#1092/#1093/#1098) and its idempotency is in #1096. Rebasing it would mean resolving conflicts against code that's already superseded. This branch is the clean residue on top of today's development.

Motivating issues: #1053 (Ready-processing delays / accumulating txs), #1054 (bridge atomicity).

Draft — not for merge until the 4 follow-ups land.

🤖 Generated with Claude Code

…harness)

Batching-focused extraction of the remaining unique work from the old
#1079 draft, rebuilt cleanly on current development. Contains the
batching API layer (unwired) and the local E2E test harness; the handler
integration is intentionally NOT included — it must be rebuilt on top of
the per-tx idempotency work (#1096) when this is picked up.

Batching API:
- clients/tfchain-client-go/batch.go: BatchCalls — submits N calls in a
  single Utility.force_batch extrinsic (continues through per-item
  failures, unlike batch/batch_all). Returns a BatchResult.
- pkg/substrate/client.go: BurnProposal/RefundProposal + BatchProposeAll
  (batched propose) and BatchSetWithdrawExecuted/BatchSetRefundTransaction-
  Executed (batched confirm), each with single-item + whole-batch fallback
  to the existing Retry* paths.
- pkg/substrate/events.go: populate the (already-declared) RefundCreatedEvents
  so the batch proposer can see RefundTransactionCreated events.

Local E2E test harness (scripts/ + Makefile + docs):
- scripts/bridge_*.js + wait_for_node.js: single- and multi-validator
  (2-of-3) end-to-end scenarios incl. crash recovery, double-spend, and
  backlog-drain.
- Makefile: bridge-dev / bridge-test / bridge-mv-* targets to spin up
  TFChain + bridge(s) and run the suite.
- bridge/docs/local_development_setup.md.

KNOWN FOLLOW-UPS before this is production-ready (from review of #1079):
1. force_batch ItemFailed carries no index — re-derive true per-item
   outcomes (IsBurnedAlready / signature presence) instead of trusting the
   aggregate count, or use Utility.batch + BatchInterrupted.Index.
2. Failure count is whole-block, phase-unfiltered — filter Utility_ItemFailed
   by the batch extrinsic's phase (mirror checkForError) and clamp.
3. No size cap — chunk calls into bounded sub-batches (avoid block-weight
   cliff on backlog drain).
4. Wire the handler integration on top of #1096's per-tx submit, and add
   Go unit tests for BatchCalls / the proposal mapping.

Motivating issues: #1053 (Ready-processing delays / accumulating txs),
#1054 (bridge atomicity).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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