mirror of
https://github.com/fluencelabs/gitbook-docs
synced 2025-06-14 23:41:32 +00:00
clean-salte main
This commit is contained in:
@ -1,2 +0,0 @@
|
||||
# Tutorials
|
||||
|
@ -1,137 +0,0 @@
|
||||
# Add Your Own Builtins
|
||||
|
||||
As discussed in the [Node]() section, some service functionalities have ubiquitous demand making them suitable candidates to be directly deployed to a peer node. The [Aqua distributed hash table](https://github.com/fluencelabs/fluence/tree/master/deploy/builtins/aqua-dht) \(DHT\) is an example of builtin service. The remainder of this tutorial guides you through the steps necessary to create and deploy a Builtin service.
|
||||
|
||||
In order to have a service available out-of-the-box with the necessary startup and scheduling scripts, we can take advantage of the Fluence [deployer feature](https://github.com/fluencelabs/fluence/tree/master/deploy) for Node native services. This feature handles the complete deployment process including
|
||||
|
||||
* module uploads,
|
||||
* service deployment and
|
||||
* script initialization and scheduling
|
||||
|
||||
Note that the deployment process is a fully automated workflow requiring you to merely submit your service assets, i.e., Wasm modules and configuration scripts, in the appropriate format as a PR to the [Fluence](https://github.com/fluencelabs/fluence) repository.
|
||||
|
||||
At this point you should have a solid grasp of creating service modules and their associated configuration files. See the [Developing Modules And Services]() section for more details.
|
||||
|
||||
Our first step is fork the [Fluence](https://github.com/fluencelabs/fluence) repo by clicking on the Fork button, upper right of the repo webpage, and follow the instructions to create a local copy. In your local repo copy, checkout a new branch with a new, unique branch name:
|
||||
|
||||
```text
|
||||
cd fluence
|
||||
git checkout -b MyBranchName
|
||||
```
|
||||
|
||||
In our new branch, we create a directory with the service name in the _deploy/builtin_ directory:
|
||||
|
||||
```text
|
||||
cd deploy/builtins
|
||||
mkdir my-new-super-service
|
||||
cd new-super-service
|
||||
```
|
||||
|
||||
Replace _my_-_new-super-service_ with your service name.
|
||||
|
||||
Now we can build and populate the required directory structure with your service assets. You should put your service files in the corresponding _my_-_new-super-service_ directory.
|
||||
|
||||
## Requirements
|
||||
|
||||
In order to deploy a builtin service, we need
|
||||
|
||||
* the Wasm file for each module required for the service
|
||||
* the blueprint file for the service
|
||||
* the optional start and scheduling scripts
|
||||
|
||||
### Blueprint
|
||||
|
||||
Blueprints capture the service name and dependencies:
|
||||
|
||||
```javascript
|
||||
// example_blueprint.json
|
||||
{
|
||||
"name": "my-new-super-service",
|
||||
"dependencies": [
|
||||
"name:my_module_1",
|
||||
"name:my_module_2",
|
||||
"hash:Hash(my_module_3.wasm)"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
where
|
||||
|
||||
* name specifies the service's name and
|
||||
* dependencies list the names of the Wasm modules or the Blake3 hash of the Wasm module
|
||||
|
||||
In the above example, _my\_module\_i_ refers to ith module created when you compiled your service code
|
||||
|
||||
{% hint style="info" %}
|
||||
The easiest way to get the Blake3 hash of our Wasm modules is to install the [b3sum](https://crates.io/crates/blake3) utility:
|
||||
|
||||
```text
|
||||
cargo install b3sum
|
||||
b3sum my_module_3.wasm
|
||||
```
|
||||
{% endhint %}
|
||||
|
||||
If you decide to use the hash approach, please use the hash for the config files names as well \(see below\).
|
||||
|
||||
### **Start Script**
|
||||
|
||||
Start scripts, which are optional, execute once after service deployment or node restarts and are submitted as _air_ files and may be accompanied by a _json_ file containing the necessary parameters.
|
||||
|
||||
```text
|
||||
;; on_start.air
|
||||
(seq
|
||||
(call relay ("some_service_alias" "some_func1") [variable1] result)
|
||||
(call relay ("some_service_alias" "some_func2") [variable2 result])
|
||||
)
|
||||
```
|
||||
|
||||
and the associated data file:
|
||||
|
||||
```javascript
|
||||
// on_start.json data for on_start.air
|
||||
{
|
||||
"variable1" : "some_string",
|
||||
"variable2" : 5,
|
||||
}
|
||||
```
|
||||
|
||||
### **Scheduling Script**
|
||||
|
||||
Scheduling scripts allow us to decouple service execution from the client and instead can rely on a cron-like scheduler running on a node to trigger our service\(s\). For a brief overview, see [additional concepts]()
|
||||
|
||||
### Directory Structure
|
||||
|
||||
Now that we got our requirements covered, we can populate the directory structure we started to lay out at the beginning of this section. As mentioned above, service deployment as a builtin is an automated workflow one our PR is accepted. Hence, it is imperative to adhere to the directory structure below:
|
||||
|
||||
```text
|
||||
-- builtins
|
||||
-- {service_alias}
|
||||
-- scheduled
|
||||
-- {script_name}_{interval_in_seconds}.air [optional]
|
||||
-- blueprint.json
|
||||
-- on_start.air [optional]
|
||||
-- on_start.json [optional]
|
||||
-- {module1_name}.wasm
|
||||
-- {module1_name}_config.json
|
||||
-- Hash(module2_name.wasm).wasm
|
||||
-- Hash(module2_name.wasm)_config.json
|
||||
...
|
||||
```
|
||||
|
||||
For a complete example, please see the [aqua-dht](https://github.com/fluencelabs/fluence/tree/master/deploy/builtins/aqua-dht) builtin:
|
||||
|
||||
```text
|
||||
fluence
|
||||
--deploy
|
||||
--builtins
|
||||
--aqua-dht
|
||||
-aqua-dht.wasm
|
||||
-aqua-dht_config.json
|
||||
-blueprint.json
|
||||
-scheduled
|
||||
-sqlite3.wasm # or 558a483b1c141b66765947cf6a674abe5af2bb5b86244dfca41e5f5eb2a86e9e.wasm
|
||||
-sqlite3_config.json # or 558a483b1c141b66765947cf6a674abe5af2bb5b86244dfca41e5f5eb2a86e9e_config.json
|
||||
```
|
||||
|
||||
which is based on the [eponymous](https://github.com/fluencelabs/aqua-dht) service project.
|
||||
|
@ -1,4 +0,0 @@
|
||||
# Building a Chat Appplication
|
||||
|
||||
Coming soon. If you really need this section, contact us through any of the social media channels or Github.
|
||||
|
@ -1,4 +0,0 @@
|
||||
# Building a Collaborative Editor
|
||||
|
||||
Coming soon. If you really need this section, contact us through any of the social media channels or Github.
|
||||
|
@ -1,238 +0,0 @@
|
||||
# Building a Frontend with JS-SDK
|
||||
|
||||
Fluence provides means to connect to the network from a javascript environment. It is currently tested to work in nodejs and modern browsers.
|
||||
|
||||
To create an application you will need two main building blocks: the JS SDK itself and the aqua compiler. Both of them are provided in a form npm packages. JS SDK wraps the air interpreter and provides a connection to the network. There is low-level api for executing air scripts and registering for service calls handlers. Aqua compiler allows to write code in aqua language and compile it into typescript code which can be directly used with the SDK.
|
||||
|
||||
Even though all the logic could be programmed by hand with raw air it is strongly recommended to use aqua.
|
||||
|
||||
### Basic usage
|
||||
|
||||
As previously said you can use Fluence with any frontend or nodejs framework. JS SDK could be as any other npm library. For the purpose of the demo we will init a bare-bones nodejs package and show you the steps needed install JS SDK and aqua compiler. Feel free to use the tool most suitable for the framework used in application, the installation process should be roughly the same
|
||||
|
||||
#### 1. Start with npm package
|
||||
|
||||
For the purpose of the demo we will use a very minimal npm package with typescript support:
|
||||
|
||||
```text
|
||||
src
|
||||
┗ index.ts (1)
|
||||
package.json (2)
|
||||
tsconfig.json
|
||||
```
|
||||
|
||||
index.ts \(1\):
|
||||
|
||||
```typescript
|
||||
async function main() {
|
||||
console.log("Hello, world!");
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
package.json \(2\):
|
||||
|
||||
```javascript
|
||||
{
|
||||
"name": "demo",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"exec": "node -r ts-node/register src/index.ts"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"ts-node": "^9.1.1",
|
||||
"typescript": "^4.2.4"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Let's test if it works:
|
||||
|
||||
```bash
|
||||
$ npm install
|
||||
$ npm run exec
|
||||
```
|
||||
|
||||
The following should be printed
|
||||
|
||||
```bash
|
||||
$ npm run exec
|
||||
|
||||
> demo@1.0.0 exec C:\work\demo
|
||||
> node -r ts-node/register src/index.ts
|
||||
|
||||
Hello, world!
|
||||
$ C:\work\demo>
|
||||
```
|
||||
|
||||
#### 2. Setting JS SDK and connecting to Fluence network
|
||||
|
||||
Install the dependencies, you will need these two packages.
|
||||
|
||||
```bash
|
||||
npm install @fluencelabs/fluence @fluencelabs/fluence-network-environment
|
||||
```
|
||||
|
||||
The first one is the SDK itself and the second is a maintained list of Fluence networks and nodes to connect to.
|
||||
|
||||
All of the communication with the Fluence network is done by using `FluenceClient`. You can create one with `createClient` function. The client encapsulates air interpreter and connects to the network through the relay. Currently any node in the network can be used a relay.
|
||||
|
||||
```typescript
|
||||
import { createClient } from "@fluencelabs/fluence";
|
||||
import { testNet } from "@fluencelabs/fluence-network-environment";
|
||||
|
||||
async function main() {
|
||||
const client = await createClient(testNet[1]);
|
||||
console.log("Is client connected: ", client.isConnected);
|
||||
|
||||
await client.disconnect();
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
Let's try it out:
|
||||
|
||||
```bash
|
||||
$ npm run exec
|
||||
|
||||
> demo@1.0.0 exec C:\work\demo
|
||||
> node -r ts-node/register src/index.ts
|
||||
|
||||
Is client connected: true
|
||||
$
|
||||
```
|
||||
|
||||
**Note**: typically you should have a single instance`FluenceClient` per application since it represents it's identity in the network. You are free to store the instance anywhere you like.
|
||||
|
||||
#### 3. Setting Up The Aqua Compiler
|
||||
|
||||
Aqua is the proffered language for the Fluence network. It can be used with javascript-based environments via npm package.
|
||||
|
||||
```bash
|
||||
npm install --save-dev @fluencelabs/aqua
|
||||
```
|
||||
|
||||
We will also need the standard library for the language
|
||||
|
||||
```text
|
||||
npm install --save-dev @fluencelabs/aqua-lib
|
||||
```
|
||||
|
||||
Let's add our first aqua file:
|
||||
|
||||
```text
|
||||
aqua (1)
|
||||
┗ demo.aqua (2)
|
||||
node_modules
|
||||
src
|
||||
┣ compiled (3)
|
||||
┗ index.ts
|
||||
package-lock.json
|
||||
package.json
|
||||
tsconfig.json
|
||||
```
|
||||
|
||||
Add two directories, one for aqua sources \(1\) and another for the typescript output \(3\)
|
||||
|
||||
Create a new text file called `demo.aqua` \(2\):
|
||||
|
||||
```text
|
||||
import "@fluencelabs/aqua-lib/builtin.aqua"
|
||||
|
||||
func demo(nodePeerId: PeerId) -> []string:
|
||||
on nodePeerId:
|
||||
res <- Peer.identify()
|
||||
<- res.external_addresses
|
||||
```
|
||||
|
||||
This script will gather the list of external addresses from some node in the network. For more information about the aqua language refer to the aqua documentation.
|
||||
|
||||
The aqua code can now be compiled by using the compiler CLI. We suggest adding a script to the package.json file like so:
|
||||
|
||||
```javascript
|
||||
...
|
||||
"scripts": {
|
||||
"exec": "node -r ts-node/register src/index.ts",
|
||||
"compile-aqua": "aqua -i ./aqua/ -o ./src/compiled"
|
||||
},
|
||||
...
|
||||
```
|
||||
|
||||
Run the compiler:
|
||||
|
||||
```bash
|
||||
npm run compile-aqua
|
||||
```
|
||||
|
||||
A typescript file should be generated like so:
|
||||
|
||||
```text
|
||||
aqua
|
||||
┗ demo.aqua
|
||||
node_modules
|
||||
src
|
||||
┣ compiled
|
||||
┃ ┗ demo.ts <--
|
||||
┗ index.ts
|
||||
package-lock.json
|
||||
package.json
|
||||
tsconfig.json
|
||||
```
|
||||
|
||||
#### 4. Consuming The Compiled Code
|
||||
|
||||
Using the code generated by the compiler is as easy as calling a function. The compiler generates all the boilerplate needed to send a particle into the network and wraps it into a single call. Note that all the type information and therefore type checking and code completion facilities are there!
|
||||
|
||||
Let's do it!
|
||||
|
||||
```typescript
|
||||
import { createClient } from "@fluencelabs/fluence";
|
||||
import { testNet } from "@fluencelabs/fluence-network-environment";
|
||||
|
||||
import { demo } from "./compiled/demo"; // import the generated file
|
||||
|
||||
async function main() {
|
||||
const client = await createClient(testNet[1]);
|
||||
console.log("Is client connected: ", client.isConnected);
|
||||
|
||||
const otherNode = testNet[2].peerId;
|
||||
const addresses = await demo(client, otherNode); // call it like a normal function in typescript
|
||||
console.log(`Node ${otherNode} is connected to: ${addresses}`);
|
||||
|
||||
await client.disconnect();
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
if everything is fine you have similar result:
|
||||
|
||||
```text
|
||||
$ npm run exec
|
||||
|
||||
> demo@1.0.0 exec C:\work\demo
|
||||
> node -r ts-node/register src/index.ts
|
||||
|
||||
Is client connected: true
|
||||
Node 12D3KooWHk9BjDQBUqnavciRPhAYFvqKBe4ZiPPvde7vDaqgn5er is connected to: /ip4/138.197.189.50/tcp/7001,/ip4/138.197.189.50/tcp/9001/ws
|
||||
|
||||
$
|
||||
```
|
||||
|
||||
### Advanced usage
|
||||
|
||||
Fluence JS SDK gives options to register own handlers for aqua vm service calls
|
||||
|
||||
**TBD**
|
||||
|
||||
### References
|
||||
|
||||
* For the list of compiler options see: [https://github.com/fluencelabs/aqua](https://github.com/fluencelabs/aqua)
|
||||
* Repository with additional examples: [**https://github.com/fluencelabs/aqua-playground**](https://github.com/fluencelabs/aqua-playground)\*\*\*\*
|
||||
|
@ -1,105 +0,0 @@
|
||||
# cUrl As A Service
|
||||
|
||||
### Overview
|
||||
|
||||
[Curl](https://curl.se/) is a widely available and used command-line tool to receive or send data using URL syntax. Chances are, you probably just used it when you set up your Fluence development environment. For Fluence services to be able to interact with the world, cUrl is one option to facilitate https calls. Since Fluence modules are Wasm IT modules, cUrl cannot not be a service intrinsic. Instead, the curl command-line tool needs to be made available and accessible at the node level. And for Fluence services to be able to interact with Curl, we need to code a cUrl adapter taking care of the mounted \(cUrl\) binary.
|
||||
|
||||
### Adapter Construction
|
||||
|
||||
The work for the cUrl adapter has been fundamentally done and is exposed by the Fluence Rust SDK. As a developer, the task remaining is to instantiate the adapter in the context of the module and services scope. The following code [snippet](https://github.com/fluencelabs/fce/tree/master/examples/url-downloader/curl_adapter) illustrates the implementation requirement.
|
||||
|
||||
```rust
|
||||
use fluence::fce;
|
||||
|
||||
use fluence::WasmLoggerBuilder;
|
||||
use fluence::MountedBinaryResult;
|
||||
|
||||
pub fn main() {
|
||||
WasmLoggerBuilder::new().build().unwrap();
|
||||
}
|
||||
|
||||
#[fce]
|
||||
pub fn download(url: String) -> String {
|
||||
log::info!("get called with url {}", url);
|
||||
|
||||
let result = unsafe { curl(vec![url]) };
|
||||
String::from_utf8(result.stdout).unwrap()
|
||||
}
|
||||
|
||||
#[fce]
|
||||
#[link(wasm_import_module = "host")]
|
||||
extern "C" {
|
||||
fn curl(cmd: Vec<String>) -> MountedBinaryResult;
|
||||
}
|
||||
```
|
||||
|
||||
with the following dependencies necessary in the Cargo.toml:
|
||||
|
||||
```rust
|
||||
fluence = { version = "=0.4.2", features = ["logger"] }
|
||||
log = "0.4.8"
|
||||
```
|
||||
|
||||
We are basically linking the [external](https://doc.rust-lang.org/std/keyword.extern.html) cUrl binary and are exposing access to it as a FCE interface called download.
|
||||
|
||||
### Code References
|
||||
|
||||
* [Mounted binaries](https://github.com/fluencelabs/fce/blob/c559f3f2266b924398c203a45863ebf2fb9252ec/fluence-faas/src/host_imports/mounted_binaries.rs)
|
||||
* [cUrl](https://github.com/curl/curl)
|
||||
|
||||
### Service Construction
|
||||
|
||||
In order to create a valid Fluence service, a service configuration is required.
|
||||
|
||||
```text
|
||||
modules_dir = "target/wasm32-wasi/release"
|
||||
|
||||
[[module]]
|
||||
name = "curl_adapter"
|
||||
logger_enabled = true
|
||||
|
||||
[mounted.mounted_binaries]
|
||||
curl = "/usr/bin/curl"
|
||||
```
|
||||
|
||||
We are specifying the location of the Wsasm file, the import name of the Wasm file, some logging housekeeping, and the mounted binary reference with the command-line call information.
|
||||
|
||||
### Remote Service Creation
|
||||
|
||||
```bash
|
||||
cargo new curl-service
|
||||
cd curl-service
|
||||
# copy the above rust code into src/main
|
||||
# copy the specified dependencies into Cargo.toml
|
||||
# copy the above service configuration into Config.toml
|
||||
|
||||
fce build --release
|
||||
```
|
||||
|
||||
You should have the Fluence module curl\_adapter.wasm in `target/wasm32-wasi/release` we can test our service with `fce-repl`.
|
||||
|
||||
### Service `Test`
|
||||
|
||||
Running the REPL, we use the `interface` command to list all available interfaces and the `call` command to run a method. Fr our purposes, we furnish the [https://duckduckgo.com/?q=Fluence+Labs](https://duckduckgo.com/?q=Fluence+Labs) url to give the the curl adapter a workout.
|
||||
|
||||
```bash
|
||||
fce-repl Config.toml
|
||||
Welcome to the FCE REPL (version 0.5.2)
|
||||
app service was created with service id = 8ad81c3a-8c5c-4730-80d1-c54cd177725d
|
||||
elapsed time 40.312376ms
|
||||
|
||||
1> interface
|
||||
Loaded modules interface:
|
||||
|
||||
curl_adapter:
|
||||
fn download(url: String) -> String
|
||||
|
||||
2> call curl_adapter download ["https://duckduckgo.com/?q=Fluence+Labs"]
|
||||
result: String("<!DOCTYPE html><html lang=\"en-US\" class=\"no-js has-zcm no-theme\"><head><meta name=\"description\" content=\"DuckDuckGo. Privacy, Simplified.\"><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\"><title>Fluence Labs at DuckDuckGo</title><link rel=\"stylesheet\" href=\"/s1963.css\" type=\"text/css\"><link rel=\"stylesheet\" href=\"/r1963.css\" type=\"text/css\"><meta name=\"robots\" content=\"noindex,nofollow\"><meta name=\"referrer\" content=\"origin\"><meta name=\"apple-mobile-web-app-title\" content=\"Fluence Labs\"><link rel=\"preconnect\" href=\"https://links.duckduckgo.com\"><link rel=\"preload\" href=\"/font/ProximaNova-Reg-webfont.woff2\" as=\"font\" type=\"font/woff2\" crossorigin=\"anonymous\" /><link rel=\"preload\" href=\"/font/ProximaNova-Sbold-webfont.woff2\" as=\"font\" type=\"font/woff2\" crossorigin=\"anonymous\" /><link rel=\"shortcut icon\" href=\"/favicon.ico\" type=\"image/x-icon\" /><link id=\"icon60\" rel=\"apple-touch-icon\" href=\"/assets/icons/meta/DDG-iOS-icon_60x60.png?v=2\"/><link id=\"icon76\" rel=\"apple-touch-icon\" sizes=\"76x76\" href=\"/assets/icons/meta/DDG-iOS-icon_76x76.png?v=2\"/><link id=\"icon120\" rel=\"apple-touch-icon\" sizes=\"120x120\" href=\"/assets/icons/meta/DDG-iOS-icon_120x120.png?v=2\"/><link id=\"icon152\" rel=\"apple-touch-icon\"s
|
||||
<snip>
|
||||
ript\">DDG.index = DDG.index || {}; DDG.index.signalSummary = \"\";</script>")
|
||||
elapsed time: 334.545388ms
|
||||
|
||||
3>
|
||||
```
|
||||
|
@ -1,4 +0,0 @@
|
||||
# Developing a Frontend Application with JS-SDK
|
||||
|
||||
Coming soon. If you really need this section, contact us through any of the social media channels or Github.
|
||||
|
@ -1,51 +0,0 @@
|
||||
# Setting Up Your Environment
|
||||
|
||||
In order to develop within the Fluence solution, [Rust](https://www.rust-lang.org/tools/install) and small number of tools are required.
|
||||
|
||||
## Rust
|
||||
|
||||
Install Rust:
|
||||
|
||||
```bash
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
```
|
||||
|
||||
once Rust is installed, we need to expand the toolchain and include [nightly build](https://rust-lang.github.io/rustup/concepts/channels.html) and the [Wasm](https://doc.rust-lang.org/stable/nightly-rustc/rustc_target/spec/wasm32_wasi/index.html) compile target.
|
||||
|
||||
```bash
|
||||
rustup install nightly
|
||||
rustup target add wasm32-wasi
|
||||
```
|
||||
|
||||
To keep Rust and the toolchains updated:
|
||||
|
||||
```bash
|
||||
rustup self update
|
||||
rustup update
|
||||
```
|
||||
|
||||
There are a number of good Rust installation and IDE integration tutorials available. [DuckDuckGo](https://duckduckgo.com/) is your friend but if that's too much effort, have a look at [koderhq](https://www.koderhq.com/tutorial/rust/environment-setup/).
|
||||
|
||||
## Fluence Tools
|
||||
|
||||
Fluence provides several tools to support developers. Fluence cli, `flcli`, facilitates the compilation of modules to the necessary wasm32-wasi target. Fluence REPL, `fce-repl`, on the other hand, is a cli tool to test and experiment with FCE modules and services locally.
|
||||
|
||||
```bash
|
||||
cargo install fcli
|
||||
cargo +nightly install frepl
|
||||
```
|
||||
|
||||
In addition, Fluence provides the [proto-distributor](https://github.com/fluencelabs/proto-distributor) tool, aka `fldist`, for service lifecyle management. From deploying services to the network to executing AIR scripts, `fldist` does it all.
|
||||
|
||||
```bash
|
||||
npm install -g @fluencelabs/fldist
|
||||
```
|
||||
|
||||
## Fluence SDK
|
||||
|
||||
For frontend development, the Fluence [JS-SDK](https://github.com/fluencelabs/fluence-js) is currently the favored, and only, tool.
|
||||
|
||||
```bash
|
||||
npm install @fluencelabs/fluence
|
||||
```
|
||||
|
@ -1,4 +0,0 @@
|
||||
# Deploy A Private Fluence Network
|
||||
|
||||
Coming soon. If you really need this section, contact us through any of the social media channels or Github.
|
||||
|
@ -1,4 +0,0 @@
|
||||
# Securing Services
|
||||
|
||||
Coming soon. If you really need this section, contact us through any of the social media channels or Github.
|
||||
|
@ -1,153 +0,0 @@
|
||||
# Deploy A Local Fluence Node
|
||||
|
||||
A significant chunk of developing and testing of Fluence services can be accomplished on an isolated, local node. In this brief tutorial we set up a local, dockerized Fluence node and test its functionality. In subsequent tutorials, we cover the steps required to join an existing network or how to run your own network.
|
||||
|
||||
The fastest way to get a Fluence node up and running is to use [docker](https://docs.docker.com/get-docker/):
|
||||
|
||||
```bash
|
||||
docker run -d --name fluence -e RUST_LOG="info" -p 7777:7777 -p 9999:9999 -p 18080 fluencelabs/fluence
|
||||
```
|
||||
|
||||
where the `-d` flag runs the container in detached mode, `-e` flag sets the environment variables, `-p` flag exposes the ports: 7777 is the tcp port, 9999 the websocket port, and, optionally, 18080 the Prometheus port.
|
||||
|
||||
Once the container is up and running, we can tail the log \(output\) with
|
||||
|
||||
```bash
|
||||
docker logs -f fluence
|
||||
|
||||
[2021-03-11T01:31:17.574274Z INFO particle_node]
|
||||
+-------------------------------------------------+
|
||||
| Hello from the Fluence Team. If you encounter |
|
||||
| any troubles with node operation, please update |
|
||||
| the node via |
|
||||
| docker pull fluencelabs/fluence:latest |
|
||||
| |
|
||||
| or contact us at |
|
||||
| github.com/fluencelabs/fluence/discussions |
|
||||
+-------------------------------------------------+
|
||||
|
||||
[2021-03-11T01:31:17.575062Z INFO server_config::fluence_config] Loading config from "/.fluence/Config.toml"
|
||||
[2021-03-11T01:31:17.575461Z INFO server_config::keys] generating a new key pair
|
||||
[2021-03-11T01:31:17.575768Z WARN server_config::defaults] New management key generated. private in base64 = VE0jt68kqa2B/SMOd3VuuPd14O2WTmj6Dl//r6VM+Wc=; peer_id = 12D3KooWNGuGgQVUA6aJMGMGqkBCFmLZqMwmp6pzmv1WLYdi7gxN
|
||||
[2021-03-11T01:31:17.575797Z INFO particle_node] AIR interpreter: "./aquamarine_0.7.3.wasm"
|
||||
[2021-03-11T01:31:17.575864Z INFO particle_node::config::certificates] storing new certificate for the key pair
|
||||
[2021-03-11T01:31:17.577028Z INFO particle_node] public key = BRqbUhVD2XQ6YcWqXW1D21n7gPg15STWTG8C7pMLfqg2
|
||||
[2021-03-11T01:31:17.577848Z INFO particle_node::node] server peer id = 12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx
|
||||
<snip>
|
||||
```
|
||||
|
||||
For future interaction with the node, we need to retain the server peer id 12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx. And if you feel the need to snoop around the container:
|
||||
|
||||
```bash
|
||||
docker exec -it fluence bash
|
||||
```
|
||||
|
||||
will get you in.
|
||||
|
||||
Now that we have a local node, we can use the `fldist` tool to interact with it. From the Quick Start, you may recall that we need the node-id and node-addr:
|
||||
|
||||
* node-id: 12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx
|
||||
* node-addr: /ip4/127.0.0.1/tcp/9999/ws/p2p/12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx
|
||||
|
||||
Let's inspect our node and check for any available modules and interfaces:
|
||||
|
||||
```bash
|
||||
fldist get_modules --node-id 12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx --node-addr /ip4/127.0.0.1/tcp/9999/ws/p2p/12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx
|
||||
client seed: 43PmCycRqLt9h3t5Dbmkc3vpNjF9qrNDEVLvQhjCQYSj
|
||||
client peerId: 12D3KooWQXTe2aFzUsYFf9mBHe4poey45nmAoa8PQwCc2iy9BLMW
|
||||
node peerId: 12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx
|
||||
[[]]
|
||||
|
||||
fldist get_interfaces --node-id 12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx --node-addr /ip4/127.0.0.1/tcp/9999/ws/p2p/12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx
|
||||
client seed: DGf3E48yr73tJbxXpfxyNiRNFsoeRgxKUCpUDYafkXaN
|
||||
client peerId: 12D3KooWEY37spzSbrg1GTFEo67p9X8cFqmYDHuzaBWWJ9aRT1G2
|
||||
node peerId: 12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx
|
||||
60000
|
||||
[ [] ]
|
||||
to expand interfaces, use get_interfaces --expand
|
||||
```
|
||||
|
||||
Since we just initiated the node, we expect no modules and no interfaces and the `fldist` queries confirm our expectations. To further explore and validate the node, we can create a small [greeting](https://github.com/fluencelabs/fce/tree/master/examples/greeting) service.
|
||||
|
||||
```bash
|
||||
mkdir fluence-greeter
|
||||
cd fluence-greeeter
|
||||
# download the greeting.wasm file into this directory
|
||||
# https://github.com/fluencelabs/fce/blob/master/examples/greeting/artifacts/greeting.wasm -- Download button to the right
|
||||
echo '{ "name":"greeting"}' > greeting_cfg.json
|
||||
```
|
||||
|
||||
We just grabbed the greeting wasm file from the Fluence repo and created a service configuration file, greeting\_cfg.json, which allow us to create a new GreetingService:
|
||||
|
||||
```bash
|
||||
fldist --node-id 12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx --node-addr /ip4/127.0.0.1/tcp/9999/ws/p2p/12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx new_service --ms /Users/bebo/localdev/fce/examples/greeting/artifacts/greeting.wasm:greeting_cfg.json -n GreetingService
|
||||
client seed: 7VtMT7dbdfuU2ewWHEo42Ysg5B9KTB5gAgM8oDEs4kJk
|
||||
client peerId: 12D3KooWRSmoTL64JVXna34myzAuKWaGkjE6EBAb9gaR4hyyyQDM
|
||||
node peerId: 12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx
|
||||
uploading blueprint GreetingService to node 12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx via client 12D3KooWRSmoTL64JVXna34myzAuKWaGkjE6EBAb9gaR4hyyyQDM
|
||||
NON-CONSTANT BLUEPRINT ID: Expected blueprint id to be predefined as 88b9b328-7c2b-44fe-8f2c-01b52db12fd9, but it was generated by node as 94d02dfe696549a98e23c5de8713e7c6d6f91694e823790a2f6dcfcc93843be3
|
||||
service id: 64551400-6296-4701-8e82-daf0b4e02751
|
||||
service created successfully
|
||||
```
|
||||
|
||||
We now have a greeting service running on our node. As always, make a note of the service id, 64551400-6296-4701-8e82-daf0b4e02751.
|
||||
|
||||
```bash
|
||||
fldist get_modules --node-id 12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx --node-addr /ip4/127.0.0.1/tcp/9999/ws/p2p/12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx
|
||||
client seed: HXoV5UfoBAtT8vM2zibm6oiTt7ecFBbP3xSF2dec4RTF
|
||||
client peerId: 12D3KooWGJ8crCtYy4es835v5dVhTbD7snyLxCQupuiq2sLSXMyA
|
||||
node peerId: 12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx
|
||||
[[{"config":{"logger_enabled":true,"logging_mask":null,"mem_pages_count":100,"mounted_binaries":null,"wasi":{"envs":null,"mapped_dirs":null,"preopened_files":[]}},"hash":"80a992ec969576289c61c4a911ba149083272166ffec2949d9d4a066532eec1d","name":"greeting"}]]
|
||||
```
|
||||
|
||||
Yep, checking once again for modules, the output confirms that the greeting service is available. Writing a small AIR script allows us to use the service:
|
||||
|
||||
```text
|
||||
(xor
|
||||
(seq
|
||||
(call relay (service "greeting") [name] result)
|
||||
(call %init_peer_id% (returnService "run") [result])
|
||||
)
|
||||
(call %init_peer_id% (returnService "run") [%last_error%])
|
||||
)
|
||||
```
|
||||
|
||||
Copy and save the script to greeting.clj and we can use our trusted `fldist` tool:
|
||||
|
||||
```bash
|
||||
fldist --node-id 12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx --node-addr /ip4/127.0.0.1/tcp/9999/ws/p2p/12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx run_air -p greeting.clj -d '{"service": "64551400-6296-4701-8e82-daf0b4e02751", "name":"Fluence"}'
|
||||
client seed: 8eXzEhypvkYST82sakeS4NeGFSyxqyCSpv2GQj3tQK5E
|
||||
client peerId: 12D3KooWLFqJwuHNe2kWF8SMgX6cm24L83JUADFcbrj5fC1z3b21
|
||||
node peerId: 12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx
|
||||
Particle id: 14db3aff-b1a9-439e-8890-d0cdc9a0bacd. Waiting for results... Press Ctrl+C to stop the script.
|
||||
===================
|
||||
[
|
||||
"Hi, Fluence"
|
||||
]
|
||||
[
|
||||
[
|
||||
{
|
||||
peer_pk: '12D3KooWLFCmDq4vDRfaxW2GA6kYnorxAiie78XzQrVDVoWEZnPx',
|
||||
service_id: '64551400-6296-4701-8e82-daf0b4e02751',
|
||||
function_name: 'greeting',
|
||||
json_path: ''
|
||||
}
|
||||
]
|
||||
]
|
||||
===================
|
||||
```
|
||||
|
||||
Yep, our node and the tools are working as expected. Going back to the logs, we can further verify the script execution:
|
||||
|
||||
```bash
|
||||
docker logs -f fluence
|
||||
<snip>
|
||||
[2021-03-12T02:42:51.041267Z INFO aquamarine::particle_executor] Executing particle 14db3aff-b1a9-439e-8890-d0cdc9a0bacd
|
||||
[2021-03-12T02:42:51.041927Z INFO particle_closures::host_closures] Executed host call "64551400-6296-4701-8e82-daf0b4e02751" "greeting" (96us 700ns)
|
||||
[2021-03-12T02:42:51.046652Z INFO particle_node::network_api] Sent particle 14db3aff-b1a9-439e-8890-d0cdc9a0bacd to 12D3KooWLFqJwuHNe2kWF8SMgX6cm24L83JUADFcbrj5fC1z3b21 @ [/ip4/172.17.0.1/tcp/61636/ws]
|
||||
```
|
||||
|
||||
Looks like our node container and logging is up and running and ready for your development use. As the Fluence team is rapidly developig, make sure you stay up to date. Check the repo or [Docke rhub](https://hub.docker.com/r/fluencelabs/fluence) and update with `docker pull fluencelabs/fluence:latest`.
|
||||
|
||||
Happy composing!
|
||||
|
@ -1,4 +0,0 @@
|
||||
# TrustGraph In Action
|
||||
|
||||
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