Skip to content

fix: Subnet splitting for new HTTP outcalls pricing - #11042

Draft
eichhorl wants to merge 2 commits into
masterfrom
eichhorl/fix-new-outcalls-subnet-splitting
Draft

fix: Subnet splitting for new HTTP outcalls pricing#11042
eichhorl wants to merge 2 commits into
masterfrom
eichhorl/fix-new-outcalls-subnet-splitting

Conversation

@eichhorl

@eichhorl eichhorl commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Background

Under the new HTTP outcalls pay-as-you-go pricing, the caller's payment is split into a per-replica allowance which is stored in the context. Each replica consumes part of this allowance to produce their share of the response. Any unspent cycles out of this allowance are transferred back to the caller (initial refund). A late replica which didn't participate in the response, may still issue its refund later, after the call already received a response. Both the initial and late refunds are credited to the canister directly.

For this purpose, there are two collections holding HTTP outcalls in the call context manager: one holding in progress requests (waiting for the response and initial refund), and one holding delivered requests (waiting for late asynchronous refunds).

Problem

During a subnet split, some canisters may move to a different subnet. Currently, all HTTP contexts stay on the original subnet (A'). Most (if not all) of the in-progress contexts will likely time out because:

  1. The committee of a fully-replicated request changed completely, and can no longer collect the required shares.
  2. The dedicated node of a non-replicated request may now be on a different subnet.
  3. The chosen (min, max, total_requests) of a flexible outcall no longer make sense on a subnet half the size.
  4. The selected committee of a flexible outcall was split into two subnets.
  5. The transform function belongs to a canister that no longer exists on the subnet.

For legacy pricing, this is generally fine, since any refund is part of the timeout response, which can still be routed to the calling canister, even if it moved to a different subnet.

However, under pay-as-you-go pricing, any refunds can no longer be credited if the canister moved to a different subnet.

Proposed Changes

Starting with this PR, we reject all in-flight HTTP contexts of canisters that were split off, and attach any outstanding refund to the response directly, without waiting for any refund shares (the call is refunded in full). This way, no new delivered context waiting for further refunds is created.

Any existing delivered contexts for migrated canisters are also removed. The outstanding refunds are inserted as refund messages into the refund pool, which are routed to the receiving canisters.

@github-actions github-actions Bot added the fix label Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant