Skip to content

Commit

Permalink
Merge branch 'feature/rust-sdk' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
tchataigner committed Oct 18, 2021
2 parents c86a153 + c361514 commit 4c63ac2
Show file tree
Hide file tree
Showing 12 changed files with 1,163 additions and 916 deletions.
4 changes: 4 additions & 0 deletions docs/sdk/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"label": "SDK",
"position": 8
}
19 changes: 19 additions & 0 deletions docs/sdk/future-work.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
sidebar_position: 5
---

# Future work

Currently, only a **Rust** SDK has been produced and can be used within the Holium protocol.

The statically typed languages that we look forward to the most after it are **AssemblyScript** and
**Golang**.

As for dynamically typed languages, **Python** and **Javascript** are deemed interesting because of the
many applications that they currently cover and the numerous libraries developed with them.

As for how the Rust SDK API behaves, it currently ingest data as whole without any optimization. Ideally,
that behavior would be changed so that data are dynamically fetched during the execution of a transformation.

If those tasks interest you or if you have any query about them please feel free to reach us on any of
our contact channel.
15 changes: 15 additions & 0 deletions docs/sdk/glossary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
e---
sidebar_position: 2
---

# Glossary

We are on a **host** running **guest** Wasm bytecode on a given **runtime**.

Compiled Wasm bytecode is called a **module**.

In each **module** we can find between one or multiple **transformation wrapper(s)**. A **transformation wrapper**
is the equivalent of a developed **pure transformation** (a function).

When instantiating a **module** in a runtime, access points to **transformation wrapper**
are called **entry points**.
22 changes: 22 additions & 0 deletions docs/sdk/rationale.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
sidebar_position: 1
---

# Rationale

The transformations ran in the Holium protocol are Wasm based, meaning that code developed to run on the CLI
has to be compiled to Wasm bytecode.

As we aim for a global approach with our protocol we try to encompass as many languages as possible, allowing
for many codebase to be usable. In that regard, one SDK should be developed per language that we wish
to be usable in the Holium protocol.

The role of an Holium SDK is to adapt a codebase to run within the Holium protocol by following the
[specifications](./specifications.md).

At first the focus is most likely to be pointed on languages that currently support direct compilation
to Wasm (mostly statically typed languages). About dynamically typed languages some research are currently
underway to study how they could be integrated as a base for transformation.



4 changes: 4 additions & 0 deletions docs/sdk/rust-sdk/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"label": "Rust SDK",
"position": 4
}
14 changes: 14 additions & 0 deletions docs/sdk/rust-sdk/constraints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
sidebar_position: 3
---

# Limitations

<!-- TODO can be fixed, to see related ticket -->
Some common Rust types are not implemented yet:
- Enum
- Tuples
- Mutex
- Result

Also, functions or structures with lifetimes are not handled.
20 changes: 20 additions & 0 deletions docs/sdk/rust-sdk/install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
sidebar_position: 1
---

# Install

The Rust SDK is the Rust implementation of the [SDK specifications](../specifications.md).

It leverages [procedural macros](https://doc.rust-lang.org/reference/procedural-macros.html) to be embedded
as seamlessly as possible in a codebase.

_Rust target_

- Add rust compilation target for `wasm32-unknown-unknown`.

_Cargo file_

- Configure Cargo.toml with `crate-type = ["cdylib"]`
- Add `holium-rs-sdk` as a dependency.

25 changes: 25 additions & 0 deletions docs/sdk/rust-sdk/usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
sidebar_position: 2
---

# Usage

## Build a module

- Use the `#[holium_bindgen]` procedural macro on every public functions and structures that should be exported.
- Compile using `cargo build --target wasm32-unkown-unknwon --release`
- Wasm bytecode can be found in `<crate_root>/target/wasm32-unkown-unknwon/release/<crate_name>.wasm`

## How does it work

- Adds `Serialize` & `Deserialize` derive code for exported structure
- Implements `GenerateNode` trait to all exported structures
- Generates wrapper function around exported function that will handle input payload and output payload

In execution :
- Receive data node as CBOR serialized from the host
- Deserialize data node and fuse it with key node to generate input payload
- Run client function with corresponding arguments
- Convert return value to data node
- Serialize data node as CBOR and send it to the host

76 changes: 76 additions & 0 deletions docs/sdk/specifications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
sidebar_position: 3
---

# Specifications

**Entry points** have the same name as the exported **pure transformation** they lead to.

When passing data from the **host** to the **guest**, Wasm is currently limited. To bypass that limit we
directly interact with the guest's **linear memory**. By using pointers and lengths we are able
to read and write complex data from and to our **module**.

Here is an overview of a given execution:

```plantuml
skinparam maxMessageSize 200
database "Data Repository" as DR
actor "Holium Client" as HC
participant "**Transformations Wrapper**\nbuilt during compilation\nwith the procedural macro,\npart of the WASM module,\nexecuted in a WASM runtime" as Wrapper
participant "**Pure Transformation**,\nother part of the WASM module,\nexecuted in a WASM runtime" as Transformation
group Recursively fetching fragments of Holium data\nfrom a repository like IPFS
DR -> HC: Fetch ""DAG-CBOR"" fragment #1.
DR -> HC: Fetch ""DAG-CBOR"" fragment #2.
DR -> HC: …
DR -> HC: Fetch ""DAG-CBOR"" fragment #N.
end
group Defragmenting Holium data
HC -> HC: Create a valid ""HoliumCBOR"" object.
end
group Executing the transformation
HC -> Wrapper: Request execution of a transformation, providing its identifier and input ""HoliumCBOR"" parameter.
alt input parameter of right type
Wrapper -> Wrapper: Deserialize the ""HoliumCBOR"" input parameter into ""Rust-type"" input parameters expected by the pure transformation.
Wrapper -> Transformation: A switch selects the right method and hands it over the ""Rust-type"" input parameters for execution..
alt successful execution
Transformation -> Transformation: Execute the pure transformation.
Transformation -> Wrapper: Return success code together with ""Rust-type"" output parameters.
Wrapper -> Wrapper: Serialize ""Rust-type"" output parameters into a ""HoliumCBOR"" object.
Wrapper -> HC: Return success code and the result of the execution as a ""HoliumCBOR"" object.
HC -> HC: Fragment ""HoliumCBOR"" object into ""DAG-CBOR"" storable fragments.
HC -> DR: Push all new ""DAG-CBOR"" fragments to the repository.
else failing execution
Transformation ->x Transformation: Fail executing the transformation.
Transformation -> Wrapper: Return failure code together with an error object.
Wrapper -> : Return failure code and the error object.
end
else input parameter of wrong type
Wrapper -> Wrapper: Fail deserializing the ""HoliumCBOR"" input parameter into ""Rust-type"" objects expected by the pure transformation.
Wrapper -> HC: Return failure code together with an error object.
end
end
```

All **wrapped transformations** must have the same signature:

`fn (ret_ptr: u32, input_ptr: u32, input_len: u32) -> ()`

All pointers and lengths refer to pointers and lengths of data on the **linear memory** of our **guest**.

`ret_ptr` contains data in a tuple of format `(u32, u32)` being the pointer and length of HoliumCBOR
return payload.

`input_ptr` and `input_len` are the pointer and length of the input payload in HoliumCBOR format that
should be used to run the transformation.
3 changes: 3 additions & 0 deletions docusaurus.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const simplePlantUML = require("@akebifiky/remark-simple-plantuml");

const lightCodeTheme = require('prism-react-renderer/themes/github');
const darkCodeTheme = require('prism-react-renderer/themes/dracula');

Expand Down Expand Up @@ -93,6 +95,7 @@ module.exports = {
// Please change this to your repo.
editUrl:
'https://github.com/facebook/docusaurus/edit/master/website/',
remarkPlugins: [simplePlantUML],
},
blog: {
showReadingTime: true,
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"write-heading-ids": "docusaurus write-heading-ids"
},
"dependencies": {
"@akebifiky/remark-simple-plantuml": "^1.0.2",
"@docusaurus/core": "2.0.0-beta.3",
"@docusaurus/preset-classic": "2.0.0-beta.3",
"@mdx-js/react": "^1.6.21",
Expand All @@ -37,4 +38,4 @@
"last 1 safari version"
]
}
}
}
Loading

0 comments on commit 4c63ac2

Please sign in to comment.