add cuckoo filter example

This commit is contained in:
boneyard93501 2021-02-25 13:24:28 -06:00
parent d9eaa1fbbb
commit 3c95cfb815
15 changed files with 769 additions and 0 deletions

View File

@ -1 +1,10 @@
# Examples
This repo holds a collection of Fluence examples and tutorials across the entire Fluence stack. If you encounter any issues or have improvement suggestions, please raise them in Issues or create a PR.
## Contributing
While the project is a still in the early stage of development, you are welcome to track progress and contribute. At the current moment we don't have detailed instructions on how to join development or which code guidelines to follow. However, you can expect more info to appear soon enough. In the meanwhile, check out the basic [contributing rules](https://github.com/fluencelabs/fluence/blob/master/CONTRIBUTING.md).
## License
Unless otherwise indicated, the applicable license is [Apache 2.0](https://github.com/fluencelabs/fluence/blob/master/LICENSE).

223
fluence-cuckoo/Readme.md Normal file
View File

@ -0,0 +1,223 @@
# Cuckoo For Coca Puffs
In this tutorial we expose a Rust [cuckoofilter](https://crates.io/crates/cuckoofilter) crate as a Fluence service, deploy it to the Fluence network and use that service in a stylized frontend Rust app.
## The Elusive Cuckoo Filter
The [Cuckoo filter](https://www.cs.cmu.edu/~dga/papers/cuckoo-conext2014.pdf) is a probabilistic data structure just like [bloom filters](https://en.wikipedia.org/wiki/Bloom_filter) but better; better, because we can not just add but also delete keys from the filter. How 'bout that. Quick note on membership tests, bloom filters and probabilities: A bloom, and cuckoo, filter definitively indicate set exclusion, e.g., item is not in filter, and probabilistically indicate set inclusion. For an awesome overview and interactive tutorial, checkout [Bloom Filters By Example](https://llimllib.github.io/bloomfilter-tutorial/).
Most Ethereum developers are familiar with bloom filters as every time a block is forged, the address of every logging contract and associated indexed fields from the logs generated by the executed transactions are added to a bloom filter, which is added to the block header. See the [Yellow paper](https://ethereum.github.io/yellowpaper/paper.pdf) for more info.
## Cuckoo Filter as a Fluence Service
Aside from the fact that cuckoo filters (CF) may be part of your distributed workflow and a service implementation comes in more than handy, there is another reason why a CF as a Service is useful: CF implementations tend to not follow a particular implementation standard and consequently are implementation specific. This makes makes sharing or re-using of filters challenging. CF as Service greatly alleviates these issues.
## Getting Started
We are assuming that you have had the opportunity to work through the Fluence [documentation](https://fluence.dev/) and have it handy as a reference when necessary.
Rather than code our own cuckoo filter, we use the awesome [cuckoofilter](https://crates.io/crates/cuckoofilter) crate as our starting point and write the wrapper functions in our [main.rs](./fce-cuckoo/src/main.rs). This turns out to be a pretty straight forward process and crate functionality nicely maps into our Fluence module except for some type limitations in the exposed function, i.e. `#[fce]` functions.
Rust is strongly typed, which is reflected in its [hashing](https://doc.rust-lang.org/std/hash/index.html), and that doesn't fully map into our module. For example, H(5_u32) != H(5_64) whereas the respective byte arrays and associated hashes are. Due to the lack of generics in WASI, we lose some of the fine-grained discrimination available in the native crate. However, this is a small price to pay for interoperability gains made.
Now that we have our module in place, we compile our code into a wasm module with Fluence `fce` command line tool and use `build.sh` to do so. If you haven't installed fce, or it's been a while:
```bash
cargo +nightly install fcli --force
```
and proceed to run the `build` script:
```bash
./build.sh
```
Let's unpack the script:
```bash
#!/bin/sh
mkdir -p artifacts
cd fce-cuckoo
cargo update
fce build --release
cd ..
rm -f artifacts/*
cp fce-cuckoo/target/wasm32-wasi/release/fce-cuckoo.wasm artifacts/
```
First, we create a new dir, `artifacts`, that serves as a convenience parking lot for our wasm modules. We then execute the typical `cargo update` followed by the `fce build --release`. The fce cli closely follows cargo and we just build the wasm module with the release flag. Finally, we copy the wasm module from the deep recesses of the compiler target directory tree to the much more convenient `artifacts` directory.
Before we proceed, we need to create a [service configuration](https://fluence.dev/docs/service-config-reference). That is, we need to specify a few attributes defining our service. This is done in the [Config.tom](./fce-cuckoo/Config.tom) file. For our purposes, we have simple specification attributes limited to name and logging. See the reference for more advanced configurations.
Now that we got our cuckoo filter wasm module and service configuration, we can explore and test our masterpiece locally using the Fluence FCE repl. In the `fce-cuckoo` dir, fire up the repl with `fce-repl Config.toml` which gets us to the command line:
```bash
Welcome to the FCE REPL (version 0.1.33)
app service was created with service id = 80580519-9da6-477c-8265-0eb27d1f89cc
elapsed time 166.494711ms
1>
```
The first ting to do is check that all our (external) interfaces are available:
```bash
1> interface
Loaded modules interface:
fce-cuckoo:
fn create_and_add_cf(data: Array<Array<U8>>) -> String
fn is_empty(cf: String) -> I32
fn memory_usage(cf: String) -> U64
fn service_info() -> String
fn delete(cf: String, items: Array<Array<U8>>) -> Array<I32>
fn create_cf(with_capacity: U32) -> String
fn contains(cf: String, items: Array<Array<U8>>) -> Array<I32>
fn len(cf: String) -> U64
fn add(data: Array<Array<U8>>) -> String
```
Looks like we're all good to go and we can now run each of those functions with the appropriate signature parameters using the <command, module name, function name, function parameter> syntax. For example,
```bash
2> call fce-cuckoo service_info []
result: String("{\"name\":\"Cuckoo Filter\",\"package\":\"https://crates.io/crates/cuckoofilter\",\"source\":\"https://github.com/axiomhq/rust-cuckoofilter\",\"version\":\"0.5.0\"}")
elapsed time: 158.616µs
```
We can also explore each functions environment variables with the `envs` command:
```3> envs fce-cuckoo service_info
Environment variables:
tmp=/var/folders/yq/fvkl2sbd14sc4_kt00pqk76r0000gn/T/80580519-9da6-477c-8265-0eb27d1f89cc/tmp
local=/var/folders/yq/fvkl2sbd14sc4_kt00pqk76r0000gn/T/80580519-9da6-477c-8265-0eb27d1f89cc/local
service_id=80580519-9da6-477c-8265-0eb27d1f89cc
```
Simply type `help` on the repl command line to see all features available.
## From Local Module To Deployed Service
For our purposes, we just want fce-cuckoo to be a granular, self-contained service and it's time to deploy it to the network. In order to manage the distribution process, we need the Fluence `fldist` tool. If you have not installed it:
```bash
npm i @fluencelabs/fldist -g
```
To recap from the [documentation](https://fluence.dev/docs): Creating a Fluence service is essentially a three-step process: upload the wasm module(s), create and upload a [blueprint](https://fluence.dev/docs/upload-example-to-the-fluence-network#create-a-blueprint), which contains all the information required for a service to be created, and the service instantiation. We can use `fldist upload`, `fldist add_blueprint`, and finally `fldist create_service` to sequentially accomplish these tasks. Or, we can use `fldist new_service` to combine all three steps. But before we go there, we need our (deployment) seed, which is a Base58 derivation from a private key. The `fldist` tool has a convenience function to help us out:
```bash
mbp16~/localdev/lw3d/fluence-cuckoo(main|●1…) % fldist create_keypair
{
id: '12D3KooWRKibxAS9NmdXcJ95GYc5CU25UTw8ABzfgNtsHkwHLnHm',
privKey: 'CAESYFf+d8V7XNXdWp1/8Lt3+beXImJP/8bYDZ6do0yBu6ur5mRAupQQGFayTLgJAhafw/zIv/9qJBjD4D6bgZdWZZjmZEC6lBAYVrJMuAkCFp/D/Mi//2okGMPgPpuBl1ZlmA==',
pubKey: 'CAESIOZkQLqUEBhWsky4CQIWn8P8yL//aiQYw+A+m4GXVmWY',
seed: '6vVXJFGhmDk3h58aGNzrGxuoK9jvrfYax1rCBJaNDnUi'
}
```
Take note of the keys and seed and keep them safe. Now that we have our seed, we can create a Fluence service.
We also need a service configuration file, which is trivial in our case, see [cuckoo_cfg.json](fce-cuckoo/cuckoo_cfg.json) and merely specifies the service name:
```bash
{
"name": "fce-cuckoo"
}
```
Almost there. We want a name for our blueprint, which should be a UUID. You can generate a valid uuid anyway you want including the nifty `uuidgen`:
```bash
mbp16~/localdev/lw3d/fluence-cuckoo/fce-cuckoo(main|●1…) % uuidgen
CD610F03-D631-4F28-B22F-AFC637373626
```
We're finally ready to deploy our service:
```bash
mbp16~/localdev/lw3d/fluence-cuckoo/fce-cuckoo(main|●1…) % fldist new_service -n CD610F03-D631-4F28-B22F-AFC637373626 --ms artifacts/fce-cuckoo.wasm:cuckoo_cfg.json -s
6vVXJFGhmDk3h58aGNzrGxuoK9jvrfYax1rCBJaNDnUi --env testnet
client seed: 6vVXJFGhmDk3h58aGNzrGxuoK9jvrfYax1rCBJaNDnUi
client peerId: 12D3KooWRKibxAS9NmdXcJ95GYc5CU25UTw8ABzfgNtsHkwHLnHm
node peerId: 12D3KooWBUJifCTgaxAUrcM9JysqCcS4CS8tiYH5hExbdWCAoNwb
uploading blueprint CD610F03-D631-4F28-B22F-AFC637373626 to node 12D3KooWBUJifCTgaxAUrcM9JysqCcS4CS8tiYH5hExbdWCAoNwb via client 12D3KooWRKibxAS9NmdXcJ95GYc5CU25UTw8ABzfgNtsHkwHLnHm
creating service d7003ece-2f94-4c44-b814-d3f0f136d526
service id: f3137ae9-e687-443d-be1a-9f20a3894d4a
service created successfully
```
Awesome. We now got our service on the Fluence testnet. As mentioned earlier, the blueprint name is the uuid we provided and upon service creation, we get bach a service reference, d7003ece-2f94-4c44-b814-d3f0f136d526, and a service id, f3137ae9-e687-443d-be1a-9f20a3894d4a, which we need in order to put our cuckoo service to work.
There are different ways to interact with our distributed service but they all go through [AIR](https://fluence.dev/docs/air-scripts), the [<b>A</b>quamarine <b>I</b>ntermediate <b>R</b>epresentation](https://github.com/fluencelabs/aquamarine). See the [air-scripts](./fce-cuckoo/air-scripts) directory for a few example scripts.
Let's test the `service_info` function we reviewed earlier and use the `cuckoo_service_info.clj`:
```bash
mbp16~/localdev/lw3d/fluence-cuckoo/fce-cuckoo(main|●1…) % fldist run_air -p air-scripts/cuckoo_service_info.clj -d '{"service": "f3137ae9-e687-443d-be1a-9f20a3894d4a"}' --env testnet
client seed: rcxj5V4CxGPqFi4Z4ddQLGYajSKa9mj9Rfi5KqJcLjX
client peerId: 12D3KooWHzbkGB8NjLpTsX7GWu687jsWy3G5Tux5DWfhj7HiYkj8
node peerId: 12D3KooWBUJifCTgaxAUrcM9JysqCcS4CS8tiYH5hExbdWCAoNwb
Particle id: 4f6803dd-efca-4e7e-83a1-7abe465e6e89. Waiting for results... Press Ctrl+C to stop the script.
===================
[
"{\"name\":\"Cuckoo Filter\",\"package\":\"https://crates.io/crates/cuckoofilter\",\"source\":\"https://github.com/axiomhq/rust-cuckoofilter\",\"license\":\"MIT\",\"version\":\"0.5.0\"}"
]
[
[
{
peer_pk: '12D3KooWBUJifCTgaxAUrcM9JysqCcS4CS8tiYH5hExbdWCAoNwb',
service_id: 'f3137ae9-e687-443d-be1a-9f20a3894d4a',
function_name: 'service_info',
json_path: ''
}
]
]
===================
```
You may have to ctrl-c to end the service.
Calling our remote `fn service_info() -> String` with the air script gives us the function return value, as expected:
```bash
[
"{\"name\":\"Cuckoo Filter\",\"package\":\"https://crates.io/crates/cuckoofilter\",\"source\":\"https://github.com/axiomhq/rust-cuckoofilter\",\"license\":\"MIT\",\"version\":\"0.5.0\"}"
]
```
Let's get ourselves a cuckoo filter:
```bash
mbp16~/localdev/lw3d/fluence-cuckoo/fce-cuckoo(main|●1…) % fldist run_air -p air-scripts/cuckoo_create_cf.clj -d '{"service": "f3137ae9-e687-443d-be1a-9f20a3894d4a"}' --env testnet
client seed: 76qEx9wTgUweViSCdLMc7Z9tma9AkawGTFWZCKZNER7Z
client peerId: 12D3KooWCeZV2qMyiaVTKUYBQXp5Moxf9gptDFHTDuCZfivZz9Fn
node peerId: 12D3KooWBUJifCTgaxAUrcM9JysqCcS4CS8tiYH5hExbdWCAoNwb
Particle id: 95f65463-f211-469a-a9e5-66c4a50e1668. Waiting for results... Press Ctrl+C to stop the script.
===================
[
[
120,
156,
237,
195,
<snip>
185,
31
]
]
[
[
{
peer_pk: '12D3KooWBUJifCTgaxAUrcM9JysqCcS4CS8tiYH5hExbdWCAoNwb',
service_id: 'f3137ae9-e687-443d-be1a-9f20a3894d4a',
function_name: 'create_cf',
json_path: ''
}
]
]
===================
```
Very cool. We now have the compressed byte representation of a cuckoo filter.
Coming soon: How to use the service from a Rust application.

BIN
fluence-cuckoo/fce-cuckoo/.DS_Store vendored Normal file

Binary file not shown.

7
fluence-cuckoo/fce-cuckoo/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
DS_Store
.repl_history
/target
**/**.bak
**/**.bk
/artifacts
keypair.json

324
fluence-cuckoo/fce-cuckoo/Cargo.lock generated Normal file
View File

@ -0,0 +1,324 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "adler"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bedc89c5c7b5550ffb9372eb5c5ffc7f9f705cc3f4a128bd4669b9745f555093"
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "byteorder"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "crc32fast"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
dependencies = [
"cfg-if",
]
[[package]]
name = "cuckoofilter"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b810a8449931679f64cd7eef1bbd0fa315801b6d5d9cdc1ace2804d6529eee18"
dependencies = [
"byteorder",
"fnv",
"rand",
"serde",
"serde_bytes",
"serde_derive",
]
[[package]]
name = "fce-cuckoo"
version = "0.1.0"
dependencies = [
"cuckoofilter",
"flate2",
"fluence",
"log",
"serde",
"serde_json",
]
[[package]]
name = "flate2"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0"
dependencies = [
"cfg-if",
"crc32fast",
"libc",
"miniz_oxide",
]
[[package]]
name = "fluence"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27d9a5e4292d7bbd809a0e968e3c3aacac91cbc5acab3e26ee1e1d726f0aab24"
dependencies = [
"fluence-sdk-macro",
"fluence-sdk-main",
]
[[package]]
name = "fluence-sdk-macro"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea1a7c75a617f827d1ba9a17b4d84e1565ab239915c63f5a85c41f89a9f1d4ba"
dependencies = [
"fluence-sdk-wit",
]
[[package]]
name = "fluence-sdk-main"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6edcc983f9517c1b6bf9f851ef27f2894a3159aaa4a2fb6c9deb2ae8ecb603fa"
dependencies = [
"fluence-sdk-macro",
"log",
"serde",
]
[[package]]
name = "fluence-sdk-wit"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b75dbdd0275160f3818db3218563d791e6c612b616cd3c5d6e66283f207f648d"
dependencies = [
"proc-macro2",
"quote",
"serde",
"serde_json",
"syn",
"uuid",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "getrandom"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
dependencies = [
"cfg-if",
"libc",
"wasi 0.10.2+wasi-snapshot-preview1",
]
[[package]]
name = "itoa"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
[[package]]
name = "libc"
version = "0.2.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "miniz_oxide"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
dependencies = [
"adler",
"autocfg",
]
[[package]]
name = "ppv-lite86"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom 0.1.16",
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom 0.1.16",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core",
]
[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "serde"
version = "1.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_bytes"
version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9"
dependencies = [
"serde",
]
[[package]]
name = "serde_derive"
version = "1.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea1c6153794552ea7cf7cf63b1231a25de00ec90db326ba6264440fa08e31486"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "uuid"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
dependencies = [
"getrandom 0.2.2",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"

View File

@ -0,0 +1,15 @@
[package]
name = "fce-cuckoo"
version = "0.1.0"
authors = ["boneyard93501 <4523011+boneyard93501@users.noreply.github.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = {version = "1.0.0" }
serde_json = {version = "1.0.62"}
cuckoofilter ={version="0.5.0", features=["serde_support"] }
log = "0.4"
fluence = { version = "0.2.18", features = ["logger"] }
flate2 = "1.0.20"

View File

@ -0,0 +1,6 @@
modules_dir = "artifacts/"
[[module]]
name = "fce-cuckoo"
logger_enabled = true

View File

@ -0,0 +1,10 @@
(xor
(seq
(call relay (service "create_cf") ["0"] result)
(call %init_peer_id% (returnService "run") [result])
)
(seq
(call relay ("op" "identity") [])
(call %init_peer_id% (returnService "run") ["XOR FAILED"])
)
)

View File

@ -0,0 +1,4 @@
(seq
(call relay (service "service_info") [] result)
(call %init_peer_id% (returnService "run") [result])
)

View File

@ -0,0 +1,12 @@
#!/bin/sh
# This script builds all subprojects and puts all created Wasm modules in one dir
mkdir -p artifacts
cd fce-cuckoo
cargo update
fce build --release
cd ..
rm -f artifacts/*
cp fce-cuckoo/target/wasm32-wasi/release/fce-cuckoo.wasm artifacts/

View File

@ -0,0 +1,3 @@
{
"name": "fce-cuckoo-2"
}

View File

@ -0,0 +1,6 @@
{
"name": "fce-cuckoo",
"mountedBinaries": None,
"preopenedFiles": None,
"mappedDirs" : None,
}

View File

@ -0,0 +1,6 @@
{
"name": "fce-cuckoo",
"mountedBinaries": None,
"preopenedFiles": None,
"mappedDirs" : None,
}

View File

@ -0,0 +1,142 @@
use cuckoofilter::{CuckooFilter, ExportedCuckooFilter};
use fluence::fce;
use serde::Serialize;
use serde_json;
use std::collections::hash_map::DefaultHasher;
use flate2::Compression;
use flate2::read::ZlibDecoder;
use flate2::write::ZlibEncoder;
use std::io::prelude::*;
type CF = CuckooFilter<DefaultHasher>;
fn main() {}
fn ser_cf(cf: CF) -> Vec<u8> {
let exp_cf: ExportedCuckooFilter = cf.export();
let ser_cf: String = serde_json::to_string(&exp_cf).unwrap();
let mut e = ZlibEncoder::new(Vec::new(), Compression::default());
e.write_all(&ser_cf.as_bytes());
e.finish().unwrap()
}
fn de_cf(cf: Vec<u8>) -> Result<CF, String> {
let mut zd = ZlibDecoder::new(&cf[..]);
let mut string_buf = String::new();
zd.read_to_string(&mut string_buf).unwrap();
let ser: std::result::Result<ExportedCuckooFilter, serde_json::Error> =
serde_json::from_str(&string_buf.as_str());
if ser.is_err() {
return Err(format!("Failed to deserialize cf: {:?}", cf));
}
Ok(cuckoofilter::CuckooFilter::<DefaultHasher>::from(
ser.unwrap(),
))
}
#[fce]
pub fn create_cf(with_capacity: String) -> Vec<u8> {
let capacity = with_capacity.parse::<u32>().unwrap();
let cf = match capacity{
0 => CuckooFilter::<DefaultHasher>::new(),
_ => CuckooFilter::<DefaultHasher>::with_capacity(capacity as usize),
};
ser_cf(cf)
}
#[fce]
// one day, this may be available
// pub fn create_and_add_cf<T: ?Sized + Hash>(data: &T) -> String {
// until then, we use bytesrings although a json string of array of values should also work
// regardless, we lose some type discrimintation as 5u32 != 5u64 where in &[u8] it is.
pub fn create_and_add_cf(data: Vec<Vec<u8>>) -> Vec<u8> {
let mut cf: CF = CuckooFilter::<DefaultHasher>::new();
for v in data.iter() {
cf.add(v);
}
ser_cf(cf)
}
#[fce]
pub fn add(cf: Vec<u8>, data: Vec<Vec<u8>>) -> Vec<u8> {
let mut cf: CF = de_cf(cf).unwrap();
let mut result = Vec::<bool>::new();
for v in data.iter() {
cf.add(v).unwrap();
// TODO check for error
}
ser_cf(cf)
}
#[fce]
pub fn delete(cf: Vec<u8>, items: Vec<Vec<u8>>) -> Vec<bool> {
let mut cf = de_cf(cf).unwrap();
let mut result = Vec::<bool>::new();
for item in items.iter() {
result.push(cf.delete(item));
}
result
}
#[fce]
pub fn contains(cf: Vec<u8>, items: Vec<Vec<u8>>) -> Vec<bool> {
let cf = de_cf(cf).unwrap();
let mut result = Vec::<bool>::new();
for item in items.iter() {
result.push(cf.contains(item));
}
result
}
#[fce]
pub fn is_empty(cf: Vec<u8>) -> bool {
let cf = de_cf(cf).unwrap();
cf.is_empty()
}
#[fce]
pub fn memory_usage(cf: Vec<u8>) -> u64 {
let cf = de_cf(cf).unwrap();
cf.memory_usage() as u64
}
#[fce]
pub fn len(cf: Vec<u8>) -> u64 {
let cf = de_cf(cf).unwrap();
cf.len() as u64
}
#[fce]
pub fn service_info() -> String {
#[derive(Serialize)]
struct ServiceInfo {
name: String,
package: String,
source: String,
license: String,
version: String,
}
let info = ServiceInfo {
name: String::from("Cuckoo Filter"),
package: String::from("https://crates.io/crates/cuckoofilter"),
source: String::from("https://github.com/axiomhq/rust-cuckoofilter"),
license: String::from("MIT"),
version: String::from("0.5.0"),
};
serde_json::to_string(&info).unwrap()
}
/*
#[fce]
pub fn smoker() {
let mut data: Vec<Vec<u8>> = Vec::new();
data.push(5_u32.to_le_bytes().to_vec());
data.push("hello".as_bytes().to_vec());
data.push("fluence".as_bytes().to_vec());
data.push(r#"{"result": 10.64}"#.as_bytes().to_vec());
}
*/

View File

@ -0,0 +1,2 @@
#!/usr/bin/env bash
fldist --env dev upload -p artifacts/fce-cuckoo.wasm --name "hey200"