Read-only Invocations #1454
Replies: 3 comments 3 replies
-
I see challenges regarding this one. The host has its own assumption regarding immutability that is different from a contract. Namely a host object is immutable, and mutable operations on a host object creates new host objects (thus mutating the host object array). And the host has numerous small value optimizations baked in with such assumption. For example,
It'll require a lot of work to level out differences in assumptions between the host and the contract. And I don't think we should expose/change the assumptions and the baked-in optimization of the host too much. |
Beta Was this translation helpful? Give feedback.
-
|
A problem to consider with the ideas in this discussion is that if a function is implicitly read-only today, someone writing a read-only may depend on it being read-only when it's read-only capability is only happenstance and not part of any guarantee the contract provides. Preventing those types of accidental dependencies is possible by having every function declare it's read-only-or-read-write intent to both the spec and the host. The spec signals to external tooling. Informing the host ensures that regardless of whether the contract writes today, if it is marked as intending to write, or not intending to be read-only, it can't be called by a read-only fn. |
Beta Was this translation helpful? Give feedback.
-
|
Just seeing this. I have a use case, a bit tangential. To make some commitments for a ZK proof, I have some helper functions. Calling them must not write anything onchain as this would reveal the elements. So I make simulations only. It is helpful to have these functions in the contract as to have a verified and static version of the code. If there was some ways to prevent a function to be called at all, this would solve that security issue. (Besides using some form of hack to ensure all calls fail if not in a simulation.) TLDR, having more tools to control the function execution and what is happening to the env would be powerful additions. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I think there would be some value for safety to make it possible to add several features that support functions being guaranteed to execute as read-only.
The motivation being that contract developers often know that areas of their code shouldn't have side-effects, and marking that area of code as read-only ensures that no side-effects are ever introduced, either by code in that area of the contract the developer is writing, or in code that the contract is calling.
We explored ideas for this previously in, and some folks (@kalepail @earrietadev @mootz12) have commented there already:
Through a combination of a few features read-only safe areas could be implemented:
&mut Env/&Envto separate read-only from read-write operations. So it becomes impossible for a dev to accidentally cause side-effects in read-only functions. This change sounds simple, but may be challenging to implement in Rust's type system.&selfvs&mut self.enable_read_only_modeis called, the current invocation will error on any attempt to write to the footprint, write an event, or change anything about the environment. That change applies to all sub-invocations too, but not parent invocations.These ideas were already shared in the SDK issue above, but the first three don't really make sense and may actually be unsafe without 4️⃣, and 4️⃣ is a protocol change.
The protocol change idea is:
enable_read_only_modethat after calling causes the host to trap on any attempt to cause a side-effect, i.e. write to storage, bump TTLs, write any ledger entry, write a system event, write a contract event. The exception being diagnostic events, which would be allowed.Note that this feature doesn't really help contract top-level invokers, because they can already invoke a contract in a read-only fashion with a read-only footprint.
Would this feature improve the safety of your contracts?
Would this feature make it safer to use untrusted dependency contracts that you call?
Thoughts?
Beta Was this translation helpful? Give feedback.
All reactions