You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: CON-1639 HTTPS outcalls pay-as-you-go and dark launch budget trackers (#10519)
## Background
Currently, HTTPS outcalls are charged upfront based on a
`max_response_bytes` parameter. This is done by subtracting the full
cost from the caller's payment. The remaining cycles are stored in the
request context and refunded once a response is delivered.
Instead, we want to introduce pay-as-you-go pricing, which charges
cycles whenever resources are consumed. This happens in three stages:
1. Base cost. This fee is charged for every request upfront
2. Per-replica cost. The remaining cycles after charging the base cost
are split evenly between the participating replicas. Each replica
consumes some of their allowance as the HTTP request is processed. In
the end, the remaining cycles are gossiped as part of refund shares.
3. Consensus cost. This fee is charged for including the aggregated HTTP
response as part of a block. The cost is covered by the sum of refund
shares that were included in the aggregated response. Cycles remaining
after charging the consensus cost are refunded to the user
asynchronously.
The per-replica cost (2.) is calculated by the "budget tracker": This
struct is instantiated with the per-replica cycles allowance, whenever a
new request is starting to be processed by the HTTP adapter. As the
response is downloaded, transformed and gossiped, the tracker charges
the consumed cycles from the initial allowance. If at any point the
remaining allowance _does not_ cover an outstanding charge, an error is
returned and a reject response is gossiped. If the initial allowance
_does_ cover all charges, the remaining cycles are refunded. To this
end, the budget tracker creates a payment receipt which is gossiped
alongside the response.
Before this PR only one budget tracker exited (`LegacyTracker`) which
doesn't compute any per-replica cost, and also doesn't refund anything.
## Proposed Changes
This PR introduces the "pay-as-you-go" budget tracker, whose purpose is
to calculate the per-replica cost for outcalls using the "pay-as-you-go"
pricing (note that such outcalls do not exist yet). This is done by
implementing the per-replica part of the pricing formula defined
[here](https://colab.research.google.com/drive/1MyZBivzU_5kQtqQ8Z71gYbrMubGrTXmv#scrollTo=vxa3d-NYyEOi)
(internal). To do this, we additionally pass the subnet's size and cycle
cost schedule to the HTTP adapter. This is needed to calculate the
correct pricing.
"Pay-as-you-go" pricing charges for the amount of bytes that are
gossiped explicitly in the case of flexible and non-replicated outcalls
(where the whole response is gossiped). To do this, we move the
truncation of oversized reject messages into the adapter, such that the
correct payload length is charged.
Additionally, we implement and start to use a `DarkLaunchTracker`. This
tracker calculates both, the real (legacy, i.e. 0) and the new
(pay-as-you-go) per-replica cost. In the end, only the "real" refund is
gossiped. However, this allows us to compare both trackers, and observe
whenever the pay-as-you-go tracker returns an out-of-cycles error, while
the legacy tracker succeeds. Such an event indicates that the outcall
would not be covered by enough cycles under the new pricing. In this
case, the canister ID is logged and a metric increased.
The legacy charging flow should be unchanged by this PR.
---------
Co-authored-by: IDX GitHub Automation <infra+github-automation@dfinity.org>
0 commit comments