Skip to content

refactor: Switch HTTP outcalls receipts to hold spent cycles instead of refunds#10726

Merged
eichhorl merged 3 commits into
masterfrom
eichhorl/spent-receipts
Jul 13, 2026
Merged

refactor: Switch HTTP outcalls receipts to hold spent cycles instead of refunds#10726
eichhorl merged 3 commits into
masterfrom
eichhorl/spent-receipts

Conversation

@eichhorl

@eichhorl eichhorl commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

As part of the new pay-as-you-go pricing for HTTP outcalls, each replica participating in the outcall reports its own cycles usage. This usage is reported as part of the response shares gossiped between peers of a subnet.

Before this PR, each node gossiped a refund share, describing the amount of cycles (out of the per-replica allowance), that the node would like to refund to the caller.

The problem with this approach is that on free subnets, the per-replica allowance is zero, in order to avoid minting cycles by mistake. This means that nodes on free subnets cannot properly report their (nominal) cycles usage, which is relevant for properly updating canister metrics.

Therefore, with this PR, nodes will instead report the amount of spent cycles (out of the per-replica allowance). In a follow up we can then allow nodes on free subnets to spend more cycles than their allowance of zero.

@eichhorl eichhorl changed the title refactor: Switch receipts to hold spent cycles refactor: Switch receipts to hold spent cycles instead of refunds Jul 10, 2026
@eichhorl eichhorl changed the title refactor: Switch receipts to hold spent cycles instead of refunds refactor: Switch HTTP outcalls receipts to hold spent cycles instead of refunds Jul 10, 2026
@eichhorl eichhorl marked this pull request as ready for review July 10, 2026 11:56
@eichhorl eichhorl requested a review from a team as a code owner July 10, 2026 11:56
@zeropath-ai

zeropath-ai Bot commented Jul 10, 2026

Copy link
Copy Markdown

No security or compliance issues detected. Reviewed everything up to 917e2f1.

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► rs/https_outcalls/consensus/benches/payload_validation.rs
    /// Builds a node's contribution to an aggregated proof: a default (zero refund) payment receipt together with that node's signature over the corresponding receipt share.
Enhancement ► rs/https_outcalls/consensus/src/payload_builder.rs
    /// Enforce the per-replica allowance on every receipt in the proof.
Enhancement ► rs/https_outcalls/consensus/src/payload_builder.rs
    /// Enforce per-replica allowance for divergence shares.
Enhancement ► rs/https_outcalls/consensus/src/payload_builder/tests.rs
    fn validate_payload_fails_for_spent_exceeding_allowance_non_replicated() { … }
► rs/https_outcalls/consensus/src/payload_builder/tests.rs
    fn validate_payload_fails_for_spent_exceeding_allowance_fully_replicated() { … }
► rs/https_outcalls/consensus/src/payload_builder/tests.rs
    fn validate_payload_fails_for_spent_exceeding_allowance_divergence() { … }
► rs/https_outcalls/consensus/src/payload_builder/tests.rs
    fn validate_payload_fails_for_spent_exceeding_allowance_flexible_response() { … }
► rs/https_outcalls/consensus/src/payload_builder/tests.rs
    fn validate_payload_fails_for_spent_exceeding_allowance_too_many_rejects() { … }
► rs/https_outcalls/consensus/src/payload_builder/tests.rs
    fn validate_payload_fails_for_spent_exceeding_allowance_responses_too_large() { … }
► rs/https_outcalls/consensus/src/payload_builder/tests.rs
    fn add_signer_with_excess_spent_to_proof(…);
Refactor ► rs/https_outcalls/consensus/src/payload_builder/utils.rs
    pub(crate) fn check_spent_allowance(…);
Refactor ► rs/interfaces/src/canister_http.rs
    /// A payment receipt claims the replica spent more than the per-replica allowance
SpentExceedsAllowance { spent: Cycles, per_replica_allowance: Cycles },
Refactor ► rs/protobuf/def/types/v1/canister_http.proto
    message CanisterHttpPaymentReceipt { spent = 1; }
Refactor ► rs/protobuf/src/gen/types/types.v1.rs
    pub spent: ::core::option::Optionsuper::super::state::queues::v1::Cycles,
Refactor ► rs/types/types/src/batch/canister_http.rs
    pub fn from(receipt: CanisterHttpPaymentReceipt) -> Self { refund -> spent }
Refactor ► rs/types/types/src/canister_http.rs
    pub spent: Cycles,
Refactor ► rs/types/types/src/crypto/hash/tests.rs
    usage updated to reflect spent instead of refund in tests

@eichhorl eichhorl added this pull request to the merge queue Jul 13, 2026
Merged via the queue into master with commit 63d0867 Jul 13, 2026
46 checks passed
@eichhorl eichhorl deleted the eichhorl/spent-receipts branch July 13, 2026 15:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants