Replies: 1 comment
-
From a preliminary read, no major complaints or improvements from me. Some questions that I raised in private conversation with @supragya: While the comment that there are drawbacks to the current native execution is done is right, the current design is assuming that native executions can be done offline in a trusted environment. What the RFC is proposing is how native executions could work online; which previously we had discussed in a hand-wavey way. I had one question - which was about the possibility of a compromised canister. Orchestrators would not know of a 'previously good turned bad' canister, but @supragya rightfully pointed out that proof generation would fail if a compromised canister had executed code in an unexpected manner. Will add more, if I find/think of anything. |
Beta Was this translation helpful? Give feedback.
-
Problem motivation
Under the current scenario, we take native execution, much for granted in terms of its real world structuring. In the current design, whenever we build for native the
token
program, the dependent call (in token transferring context) towallet
program is resolved via a function call within rust. That essentially means that when native version oftoken
is built,wallet
is statically linked. However, in real world that may not always be possible due to following scenarios:PRG1
calls another programPRG2
whose source may not be disclosed / is from another developer, this kind of static linking may not be easy / ergonomic.PRG2
is actually held in secrecy (behind closed walls) and world only knows of itsProgramIdentifier
.PRG1
has to statically link all the possible programs that may ever be involved in any execution path leading to long compilation times.PRG1
also has to maintain the right build tools to buildPRG2
so the program identifier doesn't deviate, a.k.a the problem of hermetic reproducible builds.In essence, the current design of static linking is not a very good idea.
The main idea: Orchestrator based native execution
Each native execution can essentially be modeled as a function such as:
where
A
is a message understood byprg
andR
is a message return type thatprg
returns. Much of the times, it is an element of an enum.tapes
is the execution tapes that was seen during this execution and holds tapes for all involved sub-program as well.During native execution of any program
prg
,tapes[prg]
is being populated, but since there may be sub-programs that were executed in the process,tapes
may have keys more than justprg
.Assume there exists two entities: Orchestrator and Canister defined as follows:
NativeExec
, essentially taking in(prg, args)
as request and return(ret, tapes)
. This endpoint may be called by users (humans) or canisters. Orchestrators know of their own set of locally available resolver "canisters" (the local BLOB repository) as well as a few other orchestrators should they not be able to resolveNativeExec
themselves.In such a design, any orchestrator (as long as it is connected to the web of orchestrators) can resolve
NativeExec
.Example: AMM execution
Assume the following execution:
User asks native generation for system tapes from Orchestrator 2. Here is how it will look:
Beta Was this translation helpful? Give feedback.
All reactions