-
Notifications
You must be signed in to change notification settings - Fork 469
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarify ingress expiry semantics #5080
base: master
Are you sure you want to change the base?
Conversation
🤖 Here's your preview: https://hhcgk-raaaa-aaaam-abahq-cai.icp0.io |
|
||
The synchronous call endpoint is useful for users as it removes the networking overhead of polling the IC to determine the status of their call. | ||
The synchronous call endpoint is useful for users as it removes the networking overhead of polling the IC to determine the status of their call if a terminal state is reached quickly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how to best improve it but "reached quickly" is vague, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, but imo it is simply incorrect without it...
An alternative could be the following, wdyt?
The synchronous call endpoint is useful for users as it removes the networking overhead of polling the IC to determine the status of their call if a terminal state is reached quickly. | |
The synchronous call endpoint is useful for users as it reduces the networking overhead of polling the IC to determine the status of their call. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the alternative better! Thanks!
@@ -596,7 +596,7 @@ The Internet Computer has two HTTPS APIs for canister calling: | |||
|
|||
3. The IC asks the targeted canister if it is willing to accept this message and be charged for the expense of processing it. This uses the [Ingress message inspection](#system-api-inspect-message) API for normal calls. For calls to the management canister, the rules in [The IC management canister](#ic-management-canister) apply. | |||
|
|||
4. At some point, the IC may accept the call for processing and set its status to `received`. This indicates that the IC as a whole has received the call and plans on processing it (although it may still not get processed if the IC is under high load). Furthermore, the user should also be able to ask any endpoint about the status of the pending call. | |||
4. At some point, the IC may accept the call for processing and set its status to `received`. This indicates that the IC as a whole has received the call and plans on processing it (although it may still not get processed if the IC is under high load). At the time of this transition, the call has not yet expired. Furthermore, the user should also be able to ask any endpoint about the status of the pending call. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find point 8 a bit confusing as well:
In the case that the call has been retained for long enough, but the request has not expired yet
Can we be specific on "long enough" and "has not yet expired"?
Stupid question: does this relate to the "ingress_expiriry" field?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this relates to the ingress_expiry field.
I added a few sentences about subnet time and call expiry above. Does this make it more clear what "has not expired" means here? If not, can you make a suggestion?
(let's discuss "long enough" in L646/647)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thanks! That's helpful!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not introduced by this PR, but what does "the user should be able to ask any endpoint about the status of the pending call" mean here? Doesn't the user have to go to read_state
endpoint?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does "the user should be able to ask any endpoint about the status of the pending call" mean here? Doesn't the user have to go to read_state endpoint?
I was confused by that: the user must use the read state endpoint for retrieve the status of a pending call.
|
||
Calls must stay in `replied` or `rejected` long enough for polling users to catch the response. | ||
Calls stay in `replied` or `rejected` long enough for polling users to catch the response under good networking conditions with low load. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we also be specific of what it means "long enough"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
iirc, this is vague on purpose (I asked the same question some time ago and I don't remember the answer, maybe because it will always be too short in some case, so the precise value doesn't really matter?). Can someone more familiar with the interface spec history comment on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be five minutes. Is there a reason to keep this private, @derlerd-dfinity ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't remember details of this discussion, but I could imagine the following reasons why it was decided to remain vague:
- Not specifying how long we keep things around would allow to easily change it in the future.
- Under high load (i.e., when hitting the memory limits of the ingress history) both
rejected
andreplied
statuses might immediately be transitioned todone
. So even if we specified 5 minutes here I can't see how it could be useful to an application, as the 5 minutes are just a good weather property rather than a guarantee. Applications should make sure to not rely on being able to observereplied
orrejected
anyways.
I think (2) is the more important reason.
I don't feel strongly about mentioning / not mentioning the 5 minutes, as long as it is clear that even if the application manages to get a request through and an answer back within 5 minutes it might miss the rejected
/replied
status nevertheless and instead only see the done
status.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Under high load (i.e., when hitting the memory limits of the ingress history) both rejected and replied statuses might immediately be transitioned to done. So even if we specified 5 minutes here I can't see how it could be useful to an application, as the 5 minutes are just a good weather property rather than a guarantee.
What's the motivation behind distinguishing "done" and "pruned" then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By "pruned" you mean it is no longer in the tree? If so, the motivation is that done
tells you that the message was processed and it might have been a rejected
or a replied
. For a status that is no longer in the tree (i.e., was "pruned") you know nothing, i.e., not even if it was processed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By "pruned" you mean it is no longer in the tree?
Indeed.
If so, the motivation is that done tells you that the message was processed and it might have been a rejected or a replied. For a status that is no longer in the tree (i.e., was "pruned") you know nothing, i.e., not even if it was processed.
If the message times out here, then it can end up in the "done" status although it was never processed. So the "done" status only seems to make a difference if the subnet time is less than the ingress expiry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the "done" status only seems to make a difference if the subnet time is less than the ingress expiry.
Yeah, good point.
@@ -642,16 +645,20 @@ The characteristic property of the `processing` state is that *the initial effec | |||
A call may be rejected by the IC or the canister. In either case, there is no guarantee about how much processing of the call has happened. | |||
|
|||
To avoid replay attacks, the transition from `done` or `received` to `pruned` must happen no earlier than the call's `ingress_expiry` field. | |||
If a subnet's time is greater than a call's `ingress_expiry` field and it is still unknown to the IC (i.e, it was never in state `received`, `processing`, `replied`, `rejected`, or `done`), then the call will never be in one of these states. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is still unknown to the IC (i.e, it was never in state
could we suggest how to check this, e.g., the state is unknown when the subnet's time exceeded the call's ingress expiry, but is less than the call's ingress expiry plus 5 minutes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -751,7 +758,7 @@ In order to read parts of the [The system state tree](#state-tree), the user mak | |||
|
|||
- `request_type` (`text`): Always `read_state` | |||
|
|||
- `sender`, `nonce`, `ingress_expiry`: See [Authentication](#authentication) | |||
- `sender`, `nonce`, `ingress_expiry`: See [Authentication](#authentication). `ingress_expiry` refers to this request's expiry, not the expiry of an earlier call request. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This request might not refer to any earlier call request in which case the note can be confusing.
@@ -596,7 +599,7 @@ The Internet Computer has two HTTPS APIs for canister calling: | |||
|
|||
3. The IC asks the targeted canister if it is willing to accept this message and be charged for the expense of processing it. This uses the [Ingress message inspection](#system-api-inspect-message) API for normal calls. For calls to the management canister, the rules in [The IC management canister](#ic-management-canister) apply. | |||
|
|||
4. At some point, the IC may accept the call for processing and set its status to `received`. This indicates that the IC as a whole has received the call and plans on processing it (although it may still not get processed if the IC is under high load). Furthermore, the user should also be able to ask any endpoint about the status of the pending call. | |||
4. At some point, the IC may accept the call for processing and set its status to `received`. This indicates that the IC as a whole has received the call and plans on processing it (although it may still not get processed if the IC is under high load). At the time of this transition, the call has not yet expired. Furthermore, the user should also be able to ask any endpoint about the status of the pending call. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4. At some point, the IC may accept the call for processing and set its status to `received`. This indicates that the IC as a whole has received the call and plans on processing it (although it may still not get processed if the IC is under high load). At the time of this transition, the call has not yet expired. Furthermore, the user should also be able to ask any endpoint about the status of the pending call. | |
4. At some point, the IC may accept the call for processing and set its status to `received`. This indicates that the IC as a whole has received the call and plans on processing it (although it may still not get processed if the IC is under high load). This transition can only happen before the target canister's time (as visible in the [state tree](#state-tree-time)) exceeds the [`ingress_expiry`](#http-call) field of the request which submitted the call. Furthermore, the user should also be able to ask any endpoint about the status of the pending call. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ingress_time => ingress_expiry
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, fixed
@@ -588,6 +588,9 @@ The Internet Computer has two HTTPS APIs for canister calling: | |||
- [*Asynchronous*](#http-async-call-overview) canister calling, where the user must poll the Internet Computer for the status of the canister call by _separate_ HTTPS requests. | |||
- [*Synchronous*](#http-sync-call-overview) canister calling, where the status of the canister call is in the response of the original HTTPS request. | |||
|
|||
The publicly exposed state of a subnet (including the status of calls to its canisters) evolves in rounds. Each round is associated with a discrete timestamp, see [Time](#state-tree-time). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd propose to delete this discussion here and move it to where ingress_expiry
is used, I'll make a suggestion below.
@@ -596,7 +596,7 @@ The Internet Computer has two HTTPS APIs for canister calling: | |||
|
|||
3. The IC asks the targeted canister if it is willing to accept this message and be charged for the expense of processing it. This uses the [Ingress message inspection](#system-api-inspect-message) API for normal calls. For calls to the management canister, the rules in [The IC management canister](#ic-management-canister) apply. | |||
|
|||
4. At some point, the IC may accept the call for processing and set its status to `received`. This indicates that the IC as a whole has received the call and plans on processing it (although it may still not get processed if the IC is under high load). Furthermore, the user should also be able to ask any endpoint about the status of the pending call. | |||
4. At some point, the IC may accept the call for processing and set its status to `received`. This indicates that the IC as a whole has received the call and plans on processing it (although it may still not get processed if the IC is under high load). At the time of this transition, the call has not yet expired. Furthermore, the user should also be able to ask any endpoint about the status of the pending call. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not introduced by this PR, but what does "the user should be able to ask any endpoint about the status of the pending call" mean here? Doesn't the user have to go to read_state
endpoint?
A request's
ingress_expiry
keeps raising questions.This PR adds clarifications to the different semantics for
call
andread_state
.