I propose that the Internet Computer provide a way to send some sort of idempotent egress messages. In practice, this would likely be a HTTP request to some external infrastructure.
One use case for this that comes up often is to allow canisters to send email.
I propose that those concerns be addressed by the following process:
A canister makes a new system API call that is the equivalent of “Please make a HTTP request to X” (specifying appropriate payload, headers, etc)
The “subnet” (perhaps every node, perhaps every node until some acknowledgement response is received) makes the HTTP request
The receiver is configured to treat incoming HTTP requests as idempotent, using a request ID as an idempotency token.
The receiver, depending on the nature of the action, can decide whether to take action once N requests with the same request ID have been received. For something harmless, it may perform the action when receiving the first message and do nothing when receiving subsequent requests with the same request ID. For added security, it may choose to only perform the action after receiving N requests with the same request ID.
In this scenario the receiver is the one actually sending the email, and it is up to them if and when to do so.
I’m sure there is a lot more nuance to this but I hope this straw man proposal isn’t a bad place to start.
Of course, it would be great if the canister could be informed of the response to the HTTP request (or some kind of acknowledgement that it was received)
i.e. the email was successfully sent
We would need to employ idempotency in a similar way for responses/acknowledgements as well.
This seems like a needless complication of the architecture when we will see any number of other services that will provide this same functionality but without complicating the architecture. We basically just need an event system with delivery notifications… What does calling http from the canister get us?
I get it…but you can poll. It Seems like out going http requests would confuse developers about the kind of guarantees that can be given. It temps them to break determinism or at least to ignore determinism beyond when they should for the health of their application.
For some of the use cases I can imagine, even a compromised approach like polling once per minute would create unnecessary load, not to mention the amount of cycles that would be burned over time.
I think the IC should eventually provide access to all internet protocols if possible. It must if it’s going to compete with current server technologies. For example, I would love to see a JavaScript engine compiled to Wasm and ported to the IC to enable something like a Node.js/Deno environment. Without access to basic internet protocols the utility of the IC will remain very limited in comparison to current server technologies.
Even without access to these protocols, the IC is much more capable than other blockchains. But we’re aiming much higher
These services can be offered as a part of the ecosystem with having to actually run on the blockchain. calling await mycanister.sendEmail(email) works whether you have an external service that is waiting to serve email requests or if the email is sent by an actual IC canister speaking smtp. The latter just mucks up the protocol and gives us more stuff that could break/attack vectors.
If sudograph works it doesn’t matter that it was compiled by an IC node or by my local machine.
I love the idea of a dNode. It is on my list of things to do.
I suppose I just disagree with where the functionality should be implemented. I am assuming that the best developer experience and security will be provided by a tight integration with the IC protocols. Having many separate services to perform these types of operations will be messy, possibly less secure, possibly expensive, and who knows how sustainable they would be.
With http requests as an example, I want those to be included in consensus if possible. No separate service with service providers will be needed, no separate sustainability model outside of the IC node provider rewards will be needed, no competing implementations, no separate documentation outside of the IC APIs.
Everyone polling is wasteful. One service polling and then broadcasting via classical means isn’t inefficient. Also, right now, queries are free. Ethereum has events that are built into the protocol. I was surprised that DFINITY didn’t have some thing like that as part of the protocol, but I understand that someone could build it.
How? How do you do this and maintain determinism? This is so brittle. If even a response header is different(session key/cookie) how do you decide which info in the response is important enough to agree on?
I’m not sure how. I am interested to know more about IC-530, the internal feature DFINITY seems to be working on to allow canisters to make http requests.
Canisters could at least agree on the outgoing http request I imagine. The response could come back as an ingress message of some sort.
I really don’t know how it would or if it could be implemented, but I think the tight integration should be explored first.