-
Notifications
You must be signed in to change notification settings - Fork 4
Scilla Backend Design
+----------------------+
| Blockchain Smart |
| Contract Module |
| in C++ (BC) |
+----------------------+
+ state variable
| + ^
foo.scilla | | |
& message | fetch| |
| | |update
v v |
+--------------------------------------+---------------------------------+
| |
| +-------------+ +----------------+ |
| +-----------------> |JIT Driver | +--> | Scilla Run-time| |
| | |in C++ (JITD)| | Library in C++ | |
| | +-+-------+---+ | (SRTL) | |
| | | ^ +----------------+ |
| | | | |
| | foo.scilla| | |
| | | foo.ll| |
| | | | |
| | v | |
| | +--+-------+----+ |
| | |Scilla Compiler| |
| | |in OCaml (SC) | |
| | +---------------+ |
| | |
| | |
| | |
| | Scilla Virtual Machine |
| v in OCaml & C++ (SVM) |
| +-----+-------+ |
| | JIT Cache | |
| +-------------+ |
| |
+------------------------------------------------------------------------+
The scilla backend is a virtual machine (SVM), which, given a Scilla program (shown as foo.scilla) will JIT compile and execute it. During the course of execution, it will interact with the Blockchain Smart Contract Module (BC) for fetching and updating state variables. All interactions between BC and SVM will be as shared library calls.
The Scilla compiler (SC) written in OCaml (and likely will be a separately built executable) will be invoked by the JIT driver (JITD) when it needs to compile a Scilla file. The output of SC will be LLVM-IR. This LLVM-IR can include calls to functions in the Scilla runtime library (SRTL written in C++). For example, a Scilla operation such as builtin put
(insert map key-value) can result in the generation of a call in the LLVM-IR. The SRTL function will be responsible for actual update/fetching of state, by communicating with BC.
JITD is also responsible for caching compiled Scilla files (LLVM-IR) and the consequent machine code. It will transparently fetch and update the cache. This operation must be transparent to BC and it is the responsibility of BC to provide a "cache directory" which can be operated by JITD independently.
Consider a simple contract foo.scilla which has a single transition to update it's only Map
field.
contract Mapper
()
field nmap : Map Int32 String = Emp Int32 String
transition set(k : Int32, v : String)
one = Int32 1;
k1 = builtin add k one;
nmap[k1] := v
end
When compiled with SC, this will result in the following LLVM-IR (shown here as C code for simplicity).
void set(int32_t k, const char *v)
{
int32_t k1 = k + 1;
_scilla_builtin_set_map("nmap", k1, v);
}
Note that the compiled code has only functions (for transitions), no state variables.
This LLVM-IR will be JIT compiled (into machine code) by JITD and appropriate function (Scilla transition) executed by passing in the parameters (given to JITD by BC). This execution can involve calls to SRTL, in this case, the call to _scilla_builtin_set_map
.
The definition for _scilla_builtin_set_map
(and other SRTL functions) is written in C++ (for interaction with BC), compiled and linked to JITD. _scilla_builtin_set_map
will call BC to update the state variable (nmap
), control returns back to the dynamically executed code, the function completes and we're done.
If foo.scilla was previously seen by JITD, then the compiled code is available in it's cache. JITD will avoid recompiling it and will directly execute the function (transition). The key into the cache can be the Scilla source itself (or it's hash), or preferably, by an account address provided by BC.
To converge on a protocol for BC <-> SRTL interaction for fetching and updating state variables, the following has to be decided:
- How are state variables stored. Ability to fetch or update a variable must be independent of other variables. In addition, BC must be aware of
Map
variables and must be able to fetch and update specific keys. - Can ADTs be serialized (and hence stored) in a manner that parts of it can be fetched or updated? This is a harder problem.
- How should nested
Map
s be serialized and stored.
Update: This is now described here
The high level design of SRTL is straightforward. The details (function signatures) are very much dependent on how different Scilla data types are to be represented in the imperative LLVM-IR. This is closely related to the serialization discussed above.