mirror of
https://github.com/fluencelabs/gitbook-docs
synced 2025-06-15 16:01:32 +00:00
GitBook: [docs] 54 pages and 17 assets modified
This commit is contained in:
committed by
gitbook-bot
parent
c6a1b1204a
commit
818e9f6253
2
knowledge_knowledge/README.md
Normal file
2
knowledge_knowledge/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
# Knowledgebase
|
||||
|
6
knowledge_knowledge/fluence-compute-engine.md
Normal file
6
knowledge_knowledge/fluence-compute-engine.md
Normal file
@ -0,0 +1,6 @@
|
||||
# Fluence Compute Engine
|
||||
|
||||
[Fluence Compute Engine](https://github.com/fluencelabs/fce) \(FCE\) is a general purpose WebAssembly runtime that could be used in different scenarios, especially in programs based on the [ECS](https://en.wikipedia.org/wiki/Entity_component_system) pattern or plugin architecture. It runs multi-module Wasm applications with [interface-types](https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.mdhttps://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md) and [shared-nothing](https://en.wikipedia.org/wiki/Shared-nothing_architecture) linking scheme.
|
||||
|
||||
Fluence [nodes](https://github.com/fluencelabs/fluence) use FCE to execute [Aquamarine](https://github.com/fluencelabs/aquamarine) and Wasm services.
|
||||
|
30
knowledge_knowledge/knowledge_aquamarine/README.md
Normal file
30
knowledge_knowledge/knowledge_aquamarine/README.md
Normal file
@ -0,0 +1,30 @@
|
||||
# Aquamarine
|
||||
|
||||
Aquamarine is a programming language and executable choreography tool for distributed applications and backends. Aquamarine manages the communication and coordination between services, devices, and APIs without introducing any centralized gateway and can be used to express various distributed systems: from simple request-response to comprehensive network consensus algorithms.
|
||||
|
||||
At the core of Aquamarine is the design ideal and idea to pair concurrent systems, and especially decentralized networks, with a programing and execution tool chain to avoid centralized bottlenecks commonly introduced with [workflow engines](https://en.wikipedia.org/wiki/Workflow_engine) and [Business rule engines](https://en.wikipedia.org/wiki/Business_rules_engine). This not only makes Aquamarine the rosetta stone of the Fluence solution but also a very powerful generic coordination and composition medium.
|
||||
|
||||
## Background
|
||||
|
||||
When we build systems, we need to be able to model, specify, analyze and verify them and this is especially important to concurrent systems such as parallel and multi-threaded systems. [Formal specification](https://en.wikipedia.org/wiki/Formal_specification) are a family of formal approaches to design, model, and verify system. In the context of concurrent systems, there are two distinct formal specification techniques available. The state oriented approach is concerned with modeling verifying a systems state and state transitions and is often accomplished with [TLA+](https://en.wikipedia.org/wiki/TLA%2B). Modern blockchain design, modeling, and verification tend to rely on a state-based specification.
|
||||
|
||||
An alternative, complementary approach is based on [Process calculus](https://en.wikipedia.org/wiki/Process_calculus) to model and verify the sequence of communications operations of a system at any given time. [π-Calculs](https://en.wikipedia.org/wiki/%CE%A0-calculus) is a modern process calculus employed in a wide range of applications ranging from biology to games and business processes.
|
||||
|
||||
Aquamarine, Fluence's distributed composition language and runtime, is based on π-calculus and provides a solid theoretical basis toward the design, modeling, implementation, and verification of a wide class of distributed, peer-to-peer networks, applications and backends.
|
||||
|
||||
TODO: maybe add some non-fluence examples; definitely get to the verification bit.
|
||||
|
||||
## Language
|
||||
|
||||
[Aquamarine Intermediate Representation](https://github.com/boneyard93501/docs/tree/a512080f81137fb575a5b96d3f3e83fa3044fd1c/src/knowledge-base/knowledge_aquamarine__air.md) \(AIR\) is a low-level language modelled after the [WebAssembly text format](https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format) and allows developers to manage network peers as well as services and backends. AIR, while intended as a compile target, is currently the only Aquamarine language implementation although a high level language \(HLL\) is currently under active development.
|
||||
|
||||
TODO: verify below and that we don't have parallel composition proper The Aquamarine language implementation includes
|
||||
|
||||
* sequential composition
|
||||
* reduction semantics
|
||||
* communication
|
||||
|
||||
## Runtime
|
||||
|
||||
The Aquamarine runtime is a virtual machine executed by the [Fluence Compute Engine](https://github.com/boneyard93501/docs/tree/a512080f81137fb575a5b96d3f3e83fa3044fd1c/src/knowledge-base/knowledge_fce.md) \(FCE\) running not only on every Fluence network peer but also on every frontend client. The distributed runtime availability per node not only aids in decentralized service discovery and execution at the same level of decentralization of the network, which is of significant importance. Moreover, with running execution scripts on both the client and the \(remote\) nodes, a high degree of auditability and verifiability can be attained.
|
||||
|
10
knowledge_knowledge/knowledge_aquamarine/hll.md
Normal file
10
knowledge_knowledge/knowledge_aquamarine/hll.md
Normal file
@ -0,0 +1,10 @@
|
||||
# HLL
|
||||
|
||||
### Aquamarine High Level Language
|
||||
|
||||
Since parenthesis management is a bit of a downer, we are very soon providing a high level language with AIR as the compile target. Aquamarine users, rejoice !
|
||||
|
||||
_**Stay Tuned -- Coming Soon To A Repo Near You**_
|
||||
|
||||
|
||||
|
@ -0,0 +1,55 @@
|
||||
# AIR
|
||||
|
||||
The Aquamarine Intermediate Representation \(AIR\) is a low level language to program both distributed networks and the services deployed on them. The language is comprised of five instructions:
|
||||
|
||||
* _call_: : execution
|
||||
* _seq_ : sequential
|
||||
* _par :_ parallel
|
||||
* _fold_ : iteration
|
||||
* _xor :_ branching & error handling
|
||||
* _null_ : empty instruction
|
||||
|
||||
which operate on _peer-id_ \(location\), _service-id_, and _service method_ over an argument list, see Figure 1.
|
||||
|
||||
**Figure 1: AIR Instruction Definition** 
|
||||
|
||||
## Instructions
|
||||
|
||||
AIR instructions are intended to launch the execution of a service method as follows:
|
||||
|
||||
1. The method is executed on the peer specified by the peer id \(location\) parameter
|
||||
2. The peer is expected to have the Wasm service specified by the service id parameter
|
||||
3. The service must have a callable method specified be the method parameter
|
||||
4. The arguments specified by the argument list are passed to the method
|
||||
5. The result of the method returned under the name output name
|
||||
|
||||
**Figure 2: Sequential Instruction** 
|
||||
|
||||
The seq instruction takes two instructions at most as its arguments and executes them sequentially, one after the other.
|
||||
|
||||
**Figure 3: Parallel Instruction** 
|
||||
|
||||
The par</i.> instruction takes two instructions at most as its arguments and particles may execute on parallel paths iff each service referenced is hosted on a different node otherwise particles execute sequentially
|
||||
|
||||
TODO: add better graphic showing the disticntion of branching vs seq.
|
||||
|
||||
**Figure 4: Fold Instruction** 
|
||||
|
||||
The fold instruction iterates over the elements of an array and workds as follows:
|
||||
|
||||
* fold instruction takes three arguments: an array, a variable and an instruction
|
||||
* At each iteration, the variable is assigned an element of the array and the argument-instruction is executed
|
||||
* The argument-instruction can access the variable and uses the next statement to trigger the next iteration
|
||||
|
||||
Figure 5: XOR Instruction 
|
||||
|
||||
This instruction is intended for organizing branches in the flow of execution as well as for handling errors:
|
||||
|
||||
* The XOR instruction takes two instructions as its arguments
|
||||
* The first instruction is executed and if the execution is successful, then the second instruction is ignored
|
||||
* If the first instruction fails, then the second one is executed.
|
||||
|
||||
**Figure 6: Null Instruction** 
|
||||
|
||||
This is an empty instruction: it takes no arguments and does nothing. The null instruction is useful for generating code.
|
||||
|
2
knowledge_knowledge/knowledge_aquamarine/vm.md
Normal file
2
knowledge_knowledge/knowledge_aquamarine/vm.md
Normal file
@ -0,0 +1,2 @@
|
||||
# VM
|
||||
|
44
knowledge_knowledge/knowledge_concepts.md
Normal file
44
knowledge_knowledge/knowledge_concepts.md
Normal file
@ -0,0 +1,44 @@
|
||||
# Concepts
|
||||
|
||||
Distributed, peer-to-peer networks serve a wide variety of constituents and causes but generally with the common goal of providing decentralization benefits: no single point of failure or control. Alas, the programming of and developing for peer-to-peer networks is hard. Distributed service deployment and composition are quite different from the current REST, or GraphQL, microservices model, where discovery tends to be an inherently centralized process. In distributed, peer-to-peer networks, endpoint-based service requests are discovery-based searches across peers comprising the network. The Fluence solution makes peer-to-peer development accessible and productive and empowers developers to quickly and efficiently develop, deploy, manage, and monetize distributed applications and backends.
|
||||
|
||||
At the core of the Fluence solution are Aquamarine, a new, open-source language and runtime to choreograph distributed services into robust applications, and the Fluence Compute Engine \(FCE\), an open-source Wasm runtime. These Fluence innovations combine with [libp2p](https://libp2p.io/), [Kademlia DHT](https://en.wikipedia.org/wiki/Kademlia) at the peer-to-peer network level with the portability advantages of Wasm modules to provide developers with a modern, ergonomic p2p network and development model.
|
||||
|
||||
For the purpose of mastering peer-to-peer application development and the Fluence solution, developers need to be aware of the following concepts in addition to the Fluence tools and runtimes.
|
||||
|
||||
## Module
|
||||
|
||||
Modules are logical units of code that can be used individually or in combination to create a service. In Fluence, modules are written in Rust and compiled to [Wasm IT](https://wasi.dev/) for eventual execution by the Fluence Compute Engine \(FCE\). Modules fall into three conceptual categories, which developers need to be aware of as the module type has a direct impact on service configuration:
|
||||
|
||||
* Facade Modules
|
||||
* Pure Modules
|
||||
* Effector modules
|
||||
|
||||
Facade modules expose the API of the services comprised of one or more modules. Every service has exactly one facade module.
|
||||
|
||||
Pure modules perform computations without side-effects.
|
||||
|
||||
Effector modules contain at least one computation with a side-effect, e.g., write to file or database, access eternal binaries, etc.
|
||||
|
||||
## Service
|
||||
|
||||
Services are logical compute units derived from linking of one or more Wasm modules. The linking of modules is facilitated by the Fluence Compute Engine \(FCE\) using a specially prepared configuration file. The configuration file which governs the
|
||||
|
||||
* Order of instantiation
|
||||
* Permission to resources
|
||||
* Maximum memory allocation
|
||||
|
||||
FCE uses a [shared nothing](https://en.wikipedia.org/wiki/Shared-nothing_architecture) linking scheme meaning that modules only expose functions explicitly marked to be publicly available while not sharing memeory or any other resources. It should be further noted that services can **not** call on other services directly.
|
||||
|
||||
## Blueprint
|
||||
|
||||
The configuration map associating modules with service instantiations. This is a higher level construct than the low-level FCE linking described in the services section. Blueprints capture module names, blueprint name, and blueprint id. That allows the tracking and management of modules and services on a per-peer basis.
|
||||
|
||||
## Particle
|
||||
|
||||
A particle is a data structure combining data, service execution sequence, by means of an AIR script, and additional metadata. According to the AIR script specification, a particle travels through the network triggering execution at pre-defined service stops and peer nodes updating its data at every hop. Not surprisingly, the notion, implementation and processing of particles are a salient aspect of the Fluence solution.
|
||||
|
||||
## Application
|
||||
|
||||
An application in the Fluence solution is the "frontend" to one or more services and their execution sequence. Applications are developed by coordinating one or more services into a logical compute unit and tend to live outside the Fluence network. They can be executed in various runtime environments ranging from browsers to backend daemons with the help of Fluence command-line tools or the Fluence JS-SDK.
|
||||
|
4
knowledge_knowledge/knowledge_overview.md
Normal file
4
knowledge_knowledge/knowledge_overview.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Overview
|
||||
|
||||
Developing peer-to-peer networks and applications are pretty much the only way to decentralize control and curtail censorship. In addition, public peer-to-peer networks can be designed and augmented to offer decentralized fail-over protection and network-level data replication. while proving resistant to several attacks, including Sybil and Eclipse attacks.
|
||||
|
161
knowledge_knowledge/knowledge_security.md
Normal file
161
knowledge_knowledge/knowledge_security.md
Normal file
@ -0,0 +1,161 @@
|
||||
# Security
|
||||
|
||||
In the Fluence network, an application consists of one or more services composed with Aquamarine. Services expose actions in the form of functions, and these actions may require authorization. In this section, we present the concept of Security Tetraplets: Verifiable origins of the function arguments in form of \(peer\_id, service\_id, function\_name, data\_getter\) tetraplets. This concept enables the secure composition of function calls with AIR scripts.
|
||||
|
||||
## Decouple the Authorization Service
|
||||
|
||||
Aquamarine, as a composability medium, needs to take care of many aspects of security to enable composing services of different vendors in a safe way. Let's consider the example of authorization service – a service that verifies permission:
|
||||
|
||||
\`\`\`{scala, tidy=FALSE, eval=FALSE, highlight=FALSE } // Pseudocode of a service interface service Auth: // Works only for the service creator def grant\_permission\(to\_peer: PeerId\) def check\_permission\(\): bool
|
||||
|
||||
```text
|
||||
// Pseudocode of a service interface
|
||||
service Auth:
|
||||
// Works only for the service creator
|
||||
def grant_permission(to_peer: PeerId)
|
||||
def check_permission(): bool
|
||||
```
|
||||
|
||||
The service contains all the data necessary to check that permission was granted to a given peer. That is, we have authentication and authorization logic.
|
||||
|
||||
Consider a simple Blog service with an authorization argument for writes, i.e. adding posts.
|
||||
|
||||
```text
|
||||
service Blog:
|
||||
def add_post(text: string, is_permitted: bool)
|
||||
def list_posts(): Post[]
|
||||
```
|
||||
|
||||
By decoupling the storage of posts from the user and permissions model, we add a lot of flexibility to our Blog service. Not only can we use it for, say,both personal and corporate blogs but also as a building block for more complex social interactions. Just remember, the blog service itself doesn't care about security guards, it just stores posts, that's all.
|
||||
|
||||
Let's write an AIR script that checks permissions and adds a new post where authNode is the peer running the auth service, authSrvId and blogNde is the peer hosting the blog service:
|
||||
|
||||
```text
|
||||
;; Script is slightly simplified for better readability
|
||||
;; Setting data is omitted
|
||||
(seq
|
||||
(call authNode (authSrvId "check_permission") [] token)
|
||||
(call blogNode (blogSrvId "add_post") [text token])
|
||||
)
|
||||
```
|
||||
|
||||
This is what we want to have but now let's see if we can poke holes in our security.
|
||||
|
||||
### First Try: Person in the Middle \(PITM/MITM\) Attack
|
||||
|
||||
In case check\_permission\(\) returns false, a PITM attacker intercepts the outgoing network package, takes the function output and attempts tp replace false with true. This attempt fails, however, as in Aquamarine every peer's ID is derived from its public key and every response is signed with the corresponding private key:
|
||||
|
||||
```rust
|
||||
let resp_signature = sign(particle.signature, srvId, fnName, argsHash, responseHash)
|
||||
```
|
||||
|
||||
Since only the private key holders can verifiably sign the output of a function call. Hence, attackers' attempts to change a function output or replay the output of a function call from another particle leads to particle rejection on blogNode.
|
||||
|
||||
### Second Try: Using The Wrong Service
|
||||
|
||||
Consider the following script where we set the token to true so that add\_post may assume that permission was actually given.
|
||||
|
||||
```text
|
||||
(seq
|
||||
(call %init_peer_id% ("" "get_true") [] token)
|
||||
(call blogNode (blogSrvId "add_post") [text token])
|
||||
)
|
||||
```
|
||||
|
||||
How could we overcome this potential breach? On blog service host, blogNode, the entire AIR script execution flow is verified. That is, the Aquamarine interpreter visits each instruction and checks whether the particle's data has the result of the execution of this instruction and, if it does, checks that it was done by the expected peer, service, function and with the expected arguments. This is verified by the argsHash signed within _resp\_signature_. So when the token is set to a value inside the Aquamarine interpreter, we know the origin of this data: a triplet of peerId, serviceId, functionName.
|
||||
|
||||
In our case, the data triplet is %init\_peer\_id%, "", "get\_true" but we expect authNode, authSrvId, "check\_permission" with some known constants for authNode, authSrvId as we know where we deployed the service. As the add\_post function checks this triplet along with the token argument, and will reject the particle. Hence, we failed to trick the system by fakking the argument's origin as only the Auth service is considered a valid source of truth for authorization tokens.
|
||||
|
||||
Our attack got thwarted again but we have a few more tricks up our sleeves.
|
||||
|
||||
### Third Try: Using The Wrong Piece Of Data
|
||||
|
||||
Let's make a more sophisticated AuthStatus service that provides more data associated with the current peer id:
|
||||
|
||||
```text
|
||||
struct Status:
|
||||
is_admin: bool
|
||||
is_misbehaving: bool
|
||||
|
||||
service AuthStatus:
|
||||
def get_status(): Status
|
||||
```
|
||||
|
||||
If this peer misbehaves, we set a special flag as follows:
|
||||
|
||||
```text
|
||||
;; Script is slightly simplified for better readability
|
||||
;; Setting data is omitted
|
||||
(seq
|
||||
(call authNode (authSrvId "get_status") [] status)
|
||||
(call blogNode (blogSrvId "add_post") [text status.$.is_admin])
|
||||
)
|
||||
```
|
||||
|
||||
So we pass an _is\_admin_ flag to the blogNode, as we now have a permissioned blog and all is well. Maybe.
|
||||
|
||||
The problem is that we can also pass the _is\_misbehaving_ flag to fake admin permissions and add a post. Consider other possible scenarios, where, for example, you could have a role in the status, as well as a nickname, and you need to distinguish the two, even though both are strings.
|
||||
|
||||
Recall that the origin of the result is stated with three values _peerId_, _serviceId_, _functionName_, while the origin of the argument is extended with one more attribute: the data getter. This forms a structure of four fields – the **tetraplet**:
|
||||
|
||||
```text
|
||||
struct SecurityTetraplet:
|
||||
peer_id: string
|
||||
service_id: string
|
||||
fn_name: string
|
||||
getter: string
|
||||
```
|
||||
|
||||
The Aquamarine interpreter provides this tetraplet along with each argument during the function call, which are checked by the service if deemed necessary. In fact, tetraplets are present for every argument as a vector of vectors of tetraplets:
|
||||
|
||||
```text
|
||||
pub tetraplets: Vec<Vec<SecurityTetraplet>>
|
||||
```
|
||||
|
||||
which is possible due to the use of accumulators in AIR and produced with the fold instruction. Usually, you don't need to care about them, and only the first, i.e. origin, tetraplet is set.
|
||||
|
||||
## Limitations Of The Authentication Approach
|
||||
|
||||
This strategy positions that only arguments should affect function behavior by decoupling the service from the AIR script and its input data. That is, the \(public\) service API is safe only by relying on exogenous permissions checking ascertaining that the security invariants have no access to the AIR script or input data.
|
||||
|
||||
### Only Arguments Affect The Function Execution
|
||||
|
||||
This API cannot be used safely:
|
||||
|
||||
```text
|
||||
service WrongAuth:
|
||||
def get_status_or_fail() // does not return if not authorized
|
||||
```
|
||||
|
||||
as _WrongAuth_ service cannot be used to provide the expected checks:
|
||||
|
||||
```text
|
||||
(seq
|
||||
(call authNode (authSrv "get_status_or_fail") []) ;; no return
|
||||
(call blogNode (blogSrv "add_post") [text]) ;; no data
|
||||
)
|
||||
```
|
||||
|
||||
In the above script, if _get\_status\_or\_fail_ fails, _add\_post_ never executes. But nothing prevents a user from calling _add\_post_ directly, so this design cannot be considered secure. That's why there must be an output from a security service to be provided as an argument later.
|
||||
|
||||
### Only Direct Dependencies Are Taken Into Account
|
||||
|
||||
Consider the modified WrongAuth, which takes the peer id as an argument:
|
||||
|
||||
```text
|
||||
service WrongAuth:
|
||||
def get_status(peer_id) // Status of the given peer
|
||||
```
|
||||
|
||||
In this case, a tetraplet can easily be verified that the input arguments are not compromised. However, what data is it? As arguments of _get\_status_ function are not a part of a tetraplet, we can't check that the right peer\_id was provided to the function. So from a design perspective, it is preferable for _get\_status_ to not have arguments, so that input cannot be altered.
|
||||
|
||||
What if we want to make the system secure in terms of tracking the data origin by taking the arguments into account? In this case, the verifier function _add\_post_ needs to know not only the name of the provider but also its structure, i.e., what inputs it has and, even worse, what the constraints of these inputs are and how to verify them. Since we cannot perform garbage collection easily, we need to express the model of the program, i..e., auth service and AIR script, on the verifier side.
|
||||
|
||||
This makes decomposition a pain: why decouple services if we need them to know so much about each other? That's why function calls in Aquamarine depend on the direct inputs, and direct inputs only.
|
||||
|
||||
**References**
|
||||
|
||||
* [Tetraplet implementation in the Aquamarine interpreter](https://github.com/fluencelabs/aquamarine/blob/master/crates/polyplets/src/tetraplet.rs)
|
||||
* [Example of checking tetraplets for authorization in Fluent Pad](https://github.com/fluencelabs/fluent-pad/blob/main/services/history-inmemory/src/service_api.rs#L91)
|
||||
* [Getting tetraplets with Rust SDK](https://github.com/fluencelabs/rust-sdk/blob/master/crates/main/src/call_parameters.rs#L35)
|
||||
|
71
knowledge_knowledge/knowledge_tools.md
Normal file
71
knowledge_knowledge/knowledge_tools.md
Normal file
@ -0,0 +1,71 @@
|
||||
# Tools
|
||||
|
||||
## Fluence FCE REPL
|
||||
|
||||
\`\`[`fce-repl`](https://crates.io/crates/frepl) is a command line tool \(CLI\) to locally inspect, run, and test module and service configurations making it an invaluable development tool.
|
||||
|
||||
```text
|
||||
mbp16~(:|✔) % fce-repl
|
||||
Welcome to the FCE REPL (version 0.5.2)
|
||||
app service was created with service id = 2321fc56-8cb9-497a-8abb-03d04665e1cc
|
||||
elapsed time 282.52µs
|
||||
|
||||
1> help
|
||||
Commands:
|
||||
|
||||
n/new [config_path] create a new service (current will be removed)
|
||||
l/load <module_name> <module_path> load a new Wasm module
|
||||
u/unload <module_name> unload a Wasm module
|
||||
c/call <module_name> <func_name> [args] call function with given name from given module
|
||||
i/interface print public interface of all loaded modules
|
||||
e/envs <module_name> print environment variables of a module
|
||||
f/fs <module_name> print filesystem state of a module
|
||||
h/help print this message
|
||||
q/quit/Ctrl-C exit
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Fluence Proto Distributor: FLDIST
|
||||
|
||||
\`\`[`fldist`](https://github.com/fluencelabs/proto-distributor) is a command line interface \(CLI\) to Fluence peers allowing for the lifecycle management of services and offers the fastest and most effective way to service deployment.
|
||||
|
||||
```text
|
||||
mbp16~(:|✔) % fldist --help
|
||||
Usage: fldist <cmd> [options]
|
||||
|
||||
Commands:
|
||||
fldist completion generate completion script
|
||||
fldist upload Upload selected wasm
|
||||
fldist get_modules Print all modules on a node
|
||||
fldist get_interfaces Print all services on a node
|
||||
fldist get_interface Print a service interface
|
||||
fldist add_blueprint Add a blueprint
|
||||
fldist create_service Create a service from existing blueprint
|
||||
fldist new_service Create service from a list of modules
|
||||
fldist deploy_app Deploy application
|
||||
fldist create_keypair Generates a random keypair
|
||||
fldist run_air Send an air script from a file. Send arguments to
|
||||
"returnService" back to the client to print them in the
|
||||
console. More examples in "scripts_examples" directory.
|
||||
fldist env show nodes in currently selected environment
|
||||
|
||||
Options:
|
||||
--help Show help [boolean]
|
||||
--version Show version number [boolean]
|
||||
-s, --seed Client seed [string]
|
||||
--env Environment to use
|
||||
[required] [choices: "dev", "testnet", "local"] [default: "testnet"]
|
||||
--node-id, --node PeerId of the node to use
|
||||
--node-addr Multiaddr of the node to use
|
||||
--log log level
|
||||
[required] [choices: "trace", "debug", "info", "warn", "error"] [default:
|
||||
"error"]
|
||||
--ttl particle time to live in ms
|
||||
[number] [required] [default: 60000]
|
||||
```
|
||||
|
||||
## Fluence JS SDK
|
||||
|
||||
The Fluence [JS SDK](https://github.com/fluencelabs/fluence-js) supports developers to build full-fledged applications for a variety of targets ranging from browsers to backend apps and greatly expands on the `fldist` capabilities.
|
||||
|
2
knowledge_knowledge/node/README.md
Normal file
2
knowledge_knowledge/node/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
# Node
|
||||
|
411
knowledge_knowledge/node/knowledge_node_services.md
Normal file
411
knowledge_knowledge/node/knowledge_node_services.md
Normal file
@ -0,0 +1,411 @@
|
||||
# Services
|
||||
|
||||
## Services
|
||||
|
||||
### Overview
|
||||
|
||||
Each Fluence peer is equipped with a set of "built-in" services that can be called from Aquamarine and fall into the following namespaces:
|
||||
|
||||
1. _peer_ - operations related to connectivity or state of a given peer
|
||||
2. _kad_ - Kademlia API
|
||||
3. _srv_ – management and information about services on a node
|
||||
4. _dist_ – distribution and inspection of modules and blueprints
|
||||
5. _script_ – to manage recurring scripts
|
||||
6. _op_ – basic operations on data deprecated - namespace for deprecated API Below is the reference documentation for all the existing built-in services. Please refer to the JS SDK documentation to learn how to easily use them from the JS SDK
|
||||
7. _deprecated_ - namespace for deprecated API
|
||||
|
||||
Please note that the [`fldist`](../knowledge_tools.md#fluence-proto-distributor-fldist) CLI tool, as well as the [JS SDK](../knowledge_tools.md#fluence-js-sdk), provide access to node-based services.
|
||||
|
||||
### API
|
||||
|
||||
_**peer is\_connected**_ ****
|
||||
|
||||
Checks if there is a direct connection to the peer identified by a given PeerId
|
||||
|
||||
* **Arguments**:
|
||||
* PeerId – id of the peer to check if there's a connection with
|
||||
* **Returns**: bool - true if connected to the peer, false otherwise
|
||||
|
||||
Example of a service call:
|
||||
|
||||
```text
|
||||
(call node ("peer" "is_connected") ["123D..."] ok)
|
||||
```
|
||||
|
||||
_**peer connect**_
|
||||
|
||||
Initiates a connection to the specified peer
|
||||
|
||||
* **Arguments**
|
||||
* _PeerId_ – id of the target peer
|
||||
* \_\_[_Multiaddr_](https://crates.io/crates/multiaddr) – an array of target peer's addresses
|
||||
* **Returns**: bool - true if connection was successful
|
||||
|
||||
Example of a service call:
|
||||
|
||||
```text
|
||||
(seq
|
||||
(call node ("op" "identity") ["/ip4/1.2.3.4/tcp/7777" "/ip4/1.2.3.4/tcp/9999"] addrs)
|
||||
(call node ("peer" "connect") ["123D..." addrs] ok)
|
||||
)
|
||||
```
|
||||
|
||||
**peer get\_contact**
|
||||
|
||||
Resolves the contact of a peer via [Kademlia](https://en.wikipedia.org/wiki/Kademlia)
|
||||
|
||||
* **Arguments**
|
||||
* _PeerId_ – id of the target peer
|
||||
* **Returns**: Contact - true if connection was successful
|
||||
|
||||
```text
|
||||
// get_contact return struct
|
||||
Contact {
|
||||
peer_id: PeerId,
|
||||
addresses: [Multiaddr]
|
||||
}
|
||||
```
|
||||
|
||||
Example of a service call:
|
||||
|
||||
```text
|
||||
(call node ("peer" "get_contact") ["123D..."] contact)
|
||||
```
|
||||
|
||||
**peer identify**
|
||||
|
||||
Get information about the peer
|
||||
|
||||
* **Arguments**: None
|
||||
* **Returns:** _external address_
|
||||
|
||||
```text
|
||||
{ "external_addresses": [ "/ip4/1.2.3.4/tcp/7777", "/dns4/stage.fluence.dev/tcp/19002" ] }
|
||||
```
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("peer" "identify") [] info) peer timestamp_ms
|
||||
```
|
||||
|
||||
**peer timestamp\_ms**
|
||||
|
||||
Get Unix timestamp in milliseconds
|
||||
|
||||
* **Arguments**: None
|
||||
* **Returns**: _u128_ - number of milliseconds since 1970
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("peer" "timestamp_ms") [] ts_ms)
|
||||
```
|
||||
|
||||
**peer timestamp\_sec**
|
||||
|
||||
Get Unix timestamp in seconds
|
||||
|
||||
* **Arguments**: None
|
||||
* **Returns**: _u64_ - number of seconds since 1970
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("peer" "timestamp_sec") [] ts_sec)
|
||||
```
|
||||
|
||||
**kad neighborhood**
|
||||
|
||||
Instructs node to return the locally-known nodes in the Kademlia neighborhood for a given key
|
||||
|
||||
* **Arguments**: _key_ – the peer ID \(PeerId\) of the node
|
||||
* **Returns**: _peers_ – an array of PeerIds of the nodes that are in the Kademlia neighborhood for the given hash\(key\)
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("dht" "neighborhood") [key] peers)
|
||||
```
|
||||
|
||||
Please note that this service does _not_ traverse the network and may yield incomplete neighborhood.
|
||||
|
||||
**srv create**
|
||||
|
||||
Used to create a service on a certain node.
|
||||
|
||||
* **Arguments**:
|
||||
* blueprint\_id – ID of the blueprint that has been added to the node specified in the service call by the dist add\_blueprint service.
|
||||
* **Returns**: service\_id – the service ID of the created service.
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("srv" "create") [blueprint_id] service_id)
|
||||
```
|
||||
|
||||
**srv list**
|
||||
|
||||
Used to enumerate services deployed to a peer.
|
||||
|
||||
* **Arguments**: None
|
||||
* **Returns**: a list of services running on a peer
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("srv" "list") [] services)
|
||||
```
|
||||
|
||||
**srv add\_alias**
|
||||
|
||||
Adds an alias on service, so service could be called not only by service\_id but by alias.
|
||||
|
||||
* **Argument**: alias - settable service name service\_id – ID of the service whose interface you want to name.
|
||||
* **Returns**: alias id
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("srv" "add_alias") [alias service_id])
|
||||
```
|
||||
|
||||
|
||||
|
||||
**srv get\_interface**
|
||||
|
||||
Retrieves the functional interface of a service running on the node specified in the service call.
|
||||
|
||||
* Argument: service\_id – ID of the service whose interface you want to retrieve.
|
||||
* Returns : an interface object of the following structure:
|
||||
|
||||
```text
|
||||
{
|
||||
interface: { function_signatures, record_types },
|
||||
blueprint_id: "uuid-1234...",
|
||||
service_id: "uuid-1234..."
|
||||
}
|
||||
```
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("srv" "get_interface") [service_id] interface)
|
||||
```
|
||||
|
||||
**dist add\_module**
|
||||
|
||||
Used to add modules to the node specified in the service call.
|
||||
|
||||
* Arguments:
|
||||
|
||||
* bytes – a base64 string containing the .wasm module to add.
|
||||
* config – an object of the following structure
|
||||
|
||||
```text
|
||||
{
|
||||
"name": "my_module_name"
|
||||
}
|
||||
```
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("dist" "add_module") [bytes config] hash)
|
||||
```
|
||||
|
||||
**dist list\_modules**
|
||||
|
||||
Get a list of modules available on the node
|
||||
|
||||
* Arguments: None
|
||||
* Returns: an array of objects containing module descriptions
|
||||
|
||||
```text
|
||||
[
|
||||
{
|
||||
"name": "moduleA",
|
||||
"hash": "6ebff28c",
|
||||
"config": { "name": "moduleA" }
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("dist" "list_modules") [] modules)
|
||||
```
|
||||
|
||||
**dist get\_module\_interface**
|
||||
|
||||
Get the interface of a module
|
||||
|
||||
* Arguments: hash of a module
|
||||
* Returns: an interface of the module \( see _srv get\_interface \)_ mple of service call:
|
||||
|
||||
```text
|
||||
(call node ("dist" "get_interface") [hash] interface)
|
||||
```
|
||||
|
||||
**dist add\_blueprint**
|
||||
|
||||
Used to add a blueprint to the node specified in the service call.
|
||||
|
||||
* Arguments: blueprint – an object of the following structure
|
||||
|
||||
```text
|
||||
{
|
||||
"name": "good_service",
|
||||
"dependencies": [ "hash:6ebff28c...", "hash:1e59875a...", "hash:d164a07..." ]
|
||||
}
|
||||
```
|
||||
|
||||
Where module dependencies are specified as [_blake3_](https://crates.io/crates/blake3) hashes of modules
|
||||
|
||||
* Returns: Generated blueprint id
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("dist" "add_blueprint") [blueprint] blueprint_id)
|
||||
```
|
||||
|
||||
**dist list\_blueprints**
|
||||
|
||||
Used to get the blueprints available on the node specified in the service call.
|
||||
|
||||
* Arguments: None
|
||||
* Returns: an array of blueprint structures.
|
||||
|
||||
A blueprint is an object of the following structure:
|
||||
|
||||
```text
|
||||
{
|
||||
"id": "uuid-1234-...",
|
||||
"name": "good_service",
|
||||
"dependencies": [ "hash:6ebff28c...", "hash:1e59875a...", "hash:d164a07..." ]
|
||||
}
|
||||
```
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("dist" "list_blueprints") [] blueprints)
|
||||
```
|
||||
|
||||
**script add**
|
||||
|
||||
Adds a given script to a node. That script will be called with a fixed interval with the default setting at approx. three \(3\) seconds.
|
||||
|
||||
Recurring scripts can't read variables from data, they must be literal. That means that every address or value must be specified as a literal: \(call "QmNode" \("service\_id-1234-uuid" "function"\) \["arg1" "arg2"\]\).
|
||||
|
||||
* Arguments:
|
||||
* _script_ – a string containing "literal" script
|
||||
* _interval_ – an optional string containing interval in seconds. If set, the script will be executed periodically at that interval. If omitted, the script will be executed only once. All intervals are rounded to 3 seconds. The minimum interval is 3 seconds.
|
||||
* Returns: uuid – script id that can be used to remove that script
|
||||
|
||||
Example of service call:
|
||||
|
||||
* Without an interval parameter value, the script executes once:
|
||||
|
||||
```
|
||||
(call node ("script" "add") [script] id)
|
||||
```
|
||||
|
||||
* With an interval parameter value _k_ passed as a string, the script executes every _k_ seconds \(21 in this case\)
|
||||
|
||||
```text
|
||||
(call node ("script" "add") [script "21"] id)
|
||||
```
|
||||
|
||||
**script remove**
|
||||
|
||||
Removes recurring script from a node. Only a creator of the script can delete it
|
||||
|
||||
* Arguments: _script id_ \(as received from _script add_\)
|
||||
* Returns: true if the script was deleted and false otherwise
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("script" "remove") [script_id] result)
|
||||
```
|
||||
|
||||
**script list**
|
||||
|
||||
* Arguments: None
|
||||
* Returns: A list of existing scripts on the node. Each object in the list is of the following structure:
|
||||
|
||||
```text
|
||||
{
|
||||
"id": "uuid-1234-...",
|
||||
"src": "(seq (call ...", //
|
||||
"failures": 0,
|
||||
"interval": "21s",
|
||||
"owner": "123DKooAbcEfgh..."
|
||||
}
|
||||
```
|
||||
|
||||
Example of a service call:
|
||||
|
||||
```text
|
||||
(call node ("script" "list") [] list)
|
||||
```
|
||||
|
||||
**op identity**
|
||||
|
||||
Acts as an identity function. This service returns exactly what was passed to it. Useful for moving the execution of some service topologically or for extracting some data and putting it into an output variable.
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("op" "identity") [args] result)
|
||||
```
|
||||
|
||||
**deprecated add\_provider**
|
||||
|
||||
Used in service aliasing. ****Stores the specified service provider \(provider\) in the internal storage of the node indicated in the service call and associates it with the given key \(key\). After executing add\_provider, the provider can be accessed via the get\_providers service using this key.
|
||||
|
||||
* Arguments:
|
||||
|
||||
* key – a string; usually, it is a human-readable service alias.
|
||||
* provider – the location of the service. It is an object of the following structure:
|
||||
|
||||
```text
|
||||
{
|
||||
"peer": "123D...", // PeerId of some peer in the network
|
||||
"service_id": "uuid-1234-..." // Optional service_id of the service running on the peer specified by peer
|
||||
}
|
||||
```
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("deprecated" "add_provider") [key provider])
|
||||
```
|
||||
|
||||
|
||||
|
||||
**deprecated get\_providers**
|
||||
|
||||
Used in service aliasing to retrieve providers for a given key.
|
||||
|
||||
* Arguments: _key_ – a string; usually, it is a human-readable service alias.
|
||||
* Returns: an array of objects of the following structure:
|
||||
|
||||
```text
|
||||
{
|
||||
"peer": "123D...", // required field
|
||||
"service_id": "uuid-1234-..." // optional field
|
||||
}
|
||||
```
|
||||
|
||||
Example of service call:
|
||||
|
||||
```text
|
||||
(call node ("deprecated" "get_providers") [key] providers)
|
||||
```
|
||||
|
||||
|
||||
|
2
knowledge_knowledge/node/overview.md
Normal file
2
knowledge_knowledge/node/overview.md
Normal file
@ -0,0 +1,2 @@
|
||||
# Overview
|
||||
|
4
knowledge_knowledge/trustgraph.md
Normal file
4
knowledge_knowledge/trustgraph.md
Normal file
@ -0,0 +1,4 @@
|
||||
# TrustGraph
|
||||
|
||||
Coming soon. If you really need this section, contact us through any of the social media channels or Github.
|
||||
|
Reference in New Issue
Block a user