Runners#
Runners specify execution environments for GenVM contracts.
Runner Architecture#
Identification and Packaging#
Each runner is identified by <human-readable-id>:<hash>.
human-readable-id is provided for convenience.
hash is a sha3-256 hash of its contents
Hash Format#
Hash is SHA3 256-bit hash, converted to a string with following algorithm:
def digest_to_hash_id(got_hash: bytes) -> str:
chars = '0123456789abcdfghijklmnpqrsvwxyz'
bytes_count = len(got_hash)
base32_len = (bytes_count * 8 - 1) // 5 + 1
my_hash_arr = []
for n in range(base32_len - 1, -1, -1):
b = n * 5
i = b // 8
j = b % 8
c = (got_hash[i] >> j) | (0 if i >= bytes_count - 1 else got_hash[i + 1] << (8 - j))
my_hash_arr.append(chars[c & 0x1F])
return ''.join(my_hash_arr)
This ensures that it contains no fs-illegal characters and is case insensitive.
Runner Layout#
For any of the layouts a file list is constructed. Each file in this name has:
a name
it must not start with
/path separator must be
/it must not contain
.or..path components
contents (raw bytes slice)
1. ZIP Archive#
Used if runner bytes represent a ZIP archive
2. Raw WASM#
Used if runner bytes represent a wasm file (magic matches)
Creates a minimal runner configuration
version = v0.1.0
runner.json = { "StartWasm": "file" }
file = # source bytes
3. Text-based#
Used if neither of previous worked. Must be a valid utf-8 encoded string
Resulting structure#
version = # first line if started with version, else default
runner.json = # consequent comment lines with removed comment prefix. All whitespaces are kept as-is
file = # source bytes
Example#
# v1.0.0
# {
# "Depends": "python:latest",
# "StartWasm": "python.wasm"
# }
exit(30)
version file#
This file must contain a single line with the version of genvm in v<major>.<minor>.<patch> format.
If this file is not present, the default version is used.
runner.json File#
The runner.json file defines a recursive structure of initialization actions that configure the execution environment for a contract.
Schema is available in runner.json JSON Schema.
It must be a valid JSON object with described below structure
AddEnv#
Adds an environment variable to the GenVM environment with variable interpolation support using ${} syntax.
Example#
{
"AddEnv": {
"name": "DEBUG",
"val": "true"
}
}
MapFile#
Maps files or directories from an archive to specific paths in the GenVM filesystem.
Properties#
file(string): Path within the archive. If ending with/, recursively maps all files in the directoryto(string): Absolute destination path in the GenVM filesystem
Example#
{
"MapFile": {
"file": "config/",
"to": "/etc/myapp/"
}
}
Creating a single file mapping implies RAM Consumption of
gvm-def-consts-value-memory-limiter-consts-file-mapping.
file name length in octets
SetArgs#
Sets process arguments for the GenVM environment.
Type: Array of strings
Example#
{
"SetArgs": ["exe-name", "--verbose", "--config", "/path/to/config"]
}
LinkWasm#
Links a WebAssembly file to make it available in GenVM.
Type: String (path to WebAssembly file)
{
"LinkWasm": "path/in/arch/to/module.wasm"
}
If function _initialize is present, it will be called immediately after linking.
StartWasm#
Starts a specific WebAssembly file in GenVM.
Type: String (path to WebAssembly file)
Example#
{
"StartWasm": "path/in/arch/to/module.wasm"
}
This is a terminal action in the runner configuration. It results in linking the module and calling _start function.
Depends#
Specifies a dependency on another runner by its ID and hash.
Example#
{
"Depends": "cpython:123"
}
Dependencies are processed only once, for the first request
Seq#
Executes a sequence of initialization actions.
{
"Seq": [
{ "SetArgs": ["exe-name", "--verbose", "--config", "/path/to/config"] },
{ "StartWasm": "path/in/arch/to/module.wasm" }
]
}
When#
Conditionally executes an action based on WebAssembly execution mode.
Properties#
cond: WebAssembly mode, eitherdet(deterministic) ornondet(non-deterministic)action: Action to execute when condition is met
Example#
{
"When": {
"cond": "det",
"action": { "AddEnv": {"name": "MODE", "val": "deterministic"} }
}
}
With#
Sets a runner as current without executing its action, useful for reusing files or creating runner locks.
Example#
{
"With": {
"runner": "base-environment",
"action": { "MapFile": {"file": "patched.foo", "to": "foo" } }
}
}
Startup#
Runner actions are executed left-recursively, until StartWasm is reached.
If it was not reached, it will result in a VMError with error_inval code.
Loading a runner implies RAM Consumption of its size in octets. Each loading in a single contract, but different sub-VM instances, leads to additional RAM consumption. Deterministic Mode and Non-Deterministic Mode have separate RAM limits.
Comment Header Format#
The contract source code must begin with comment lines using one of the supported comment syntaxes:
//(C-style comments)#(Shell/Python-style comments)--(SQL/Lua/Haskell-style comments)The comment header consists of:
Version Line (first comment line): Must start with
vfollowed by version information:term:`Runner` Configuration (subsequent comment lines): JSON configuration for the runner