c3cea695c8
`air-trace run` subcommand allows to run AquaVM on any data, it allows to define most AquaVM inputs, providing defaults for most of them, and sets up either human-readable or JSON tracing output, the latter can be later processed by `air-trace stats`. Anomaly data input is also supported, that is useful for slow data investigation. Native execution mode can be used for native profiling. Please note, however, that current version cannot be built natively on Apple Sillicon processor yet, as invariably depends on the `avm-server` because of leaking types that should be refactored or hidden. The `--repeat` option can repeat the execution several times for the execution to dominate on input data reading and output. High-level or rare calls have "info" trace level, instructions are "debug", and sub-instruction calls are "tracing". Over-detailed tracing can induce overhead that spoils timing data. |
||
---|---|---|
.cargo | ||
.github | ||
air | ||
air-interpreter | ||
avm | ||
crates | ||
docs | ||
images | ||
tools/cli | ||
.gitignore | ||
Cargo.lock | ||
Cargo.toml | ||
CHANGELOG.md | ||
Config.toml | ||
LICENSE | ||
next-hardfork-changes.md | ||
README.md |
AquaVM
AquaVM executes compiled Aqua, i.e., Aqua Intermediate Representation (AIR) scripts, and plays an integral part in the implementation of the Fluence peer-to-peer compute protocol. Specifically, AquaVM allows expressing network choreography in scripts and composing distributed, peer-to-peer hosted services. Moreover, AquaVM plays a significant role in facilitating function addressability in the Fluence network. Figure 1.
Figure 1: Stylized AquaVM And AIR Model
Since AquaVM compiles to Wasm, it can run in both client, such as browsers and nodejs apps, and server environments.
AquaVM: Interpreter Execution Model
AquaVM's execution model facilitates Fluence protocol's data push model implemented as a particle, i.e., a smart packet comprised of data, AIR, and some metadata. In this context, AquaVM can be viewed as a pure state transition function that facilitates particle updates, which includes state management of particle data by taking previous and current state to produce a new state and an updated list of peers and call requests in the remaining AIR workflow. In addition to local service call execution, AquaVM handles requests from remote peers, e.g. as part of a parallel execution block, to call local services and handle the future response. See Figure 2.
Figure 2: AquaVM Interpreter Execution Model
In summary, the AquaVM execution model handles the topological hops for simple and advanced composition patters, such as (async) parallel service execution on one or multiple peers.
Aquamarine Intermediate Representation (AIR): IR For P2P Systems
AIR scripts control the Fluence peer-to-peer network, its peers and, through Marine adapter services, even resources on other (p2p) networks, such as IPFS and Filecoin, e.g., Fluence IPFS library.
What is AIR?
- S-expression-based low-level language with binary form to come
- Consists of twelve (12) instructions with more instructions to come
- Semantics are inspired by π-calculus, λ-calculus and category theory
- Syntax is inspired by Wasm Text Format (WAT) and Lisp
AIR: Instructions
call
(call <peer_id> (<service name> <service function>) [<arguments list>] <output name>)
- moves execution to the
peer_id
specified - the peer is expected to host Wasm service with the specified
service name
- the
service function
is expected to contain the specified function - the
arguments list
is given to the function and may be empty - the result of the function execution is saved and returned by it's
output name
Example:
(call "peer_id" ("dht" "put") [key value] result)
seq
(seq <left_instruction> <right_instruction>)
- executes instructions sequentially:
right_instruction
will be executed iffleft_instruction
finished successfully
par
(par <left_instruction> <right_instruction>)
- executes instructions in parallel:
right_instruction
will be executed independently of the completion ofleft_instruction
ap
(ap <literal> <dst_variable>)
(ap <src_variable>.$.<lambda> <dst_variable>)
- puts
literal
intodst_variable
- or applies
lambda
tosrc_variable
and saves the result indst_variable
Example:
(seq
(call "peer_id" ("user-list" "get_users") [] users)
(ap users.$.[0].peer_id user_0)
)
match/mismath
(match <variable> <variable> <instruction>)
(mismatch <variable> <variable> <instruction>)
- executes the instruction iff variables are equal/notequal
Example:
(seq
(call "peer_id" ("user-list" "get_users") [] users)
(mismatch users.$.length 0
(ap users.$.[0].peer_id user_0)
)
)
fold/next
(fold <iterable> <iterator> <instruction>)
- is a form of a fixed-point combinator
- iterates through the
iterable
, assigning each element to theiterator
- on each iteration
instruction
is executed next
triggers next iteration
Example:
(fold users user
(seq
(call user.$.peer_id ("chat" "display") [msg])
(next user)
)
)
xor
(xor <left_instruction> <right_instruction>)
right_instruction
is executed iffleft_instruction
failed
new
(new <variable>)
- creates a new scoped variable with the provided name (it's similar to \mu operator from pi-calculus that creates an anonymous channel)
fail
(fail <variable>)
(fail <error code> <error message>)
- throws an exception with provided
error code
anderror message
or construct it from a providedvariable
]
Example
(fail 1337 "error message")
null
(null)
- does nothing, useful for code generation
AIR: values
Scalars
- scalars are fully consistent - have the same value on each peer during a script execution
- could be an argument of any instruction
- JSON-based (fold could iterate only over array-based value)
Streams
- streams are CRDT-like (locally-consistent) - have deterministic execution wrt one peer
- versioned
- could be used only by call and fold instructions (more instructions for streams to come)
- could be turned to scalar (canonicalized)