This repository is a PoC demonstrating the capacity to use the IOTA-Streams-Channels protocol from an ESP32 device using the Rust client implementation.
espressif/rust-esp32-example has been used as boilerplate. To compile, we need a fork of LLVM and a fork of Rustc. This compilation environment is provided in the Docker image espressif/idf-rust. To run the binary an ESP32 QEMU is available in the Docker image mluis/qemu-esp32.
At the time of writing (14-10-2021), this PoC is capable of running in a Pycom LoPy board, performing:
- Create bucket transport (ie store messages in heap memory using HashMap)
- Create instance of Author
- Generate ed25519 and x25519 key pairs
- Create instance of Subscriber
- Generate ed25519 and x25519 key pairs
- Author send announcement message
- Sign with ed25519
- Subscriber send subscribe message
- Generate random unsubscription key
- Perform Diffie-Hellman exchange
- Wrap unsubscription key with DH shared secret
- Author send Keyload message (note: without subscribers this does kind of nothing)
- Generate random encryption key
- Perform Diffie-Hellman exchange
- Wrap encryption key with DH shared secret
- Subscriber receive keyload message
- Perform Diffie-Hellman exchange
- Unwrap encryption key with DH shared secret
- Author send signed packet (x2)
- Encrypt masked payload with encryption key
- Sign with ed25519
- Subscriber receives signed packets
- Call esp-idf C lib from Rust
rand::rngs::ThreadRng
is not supported (linker error) and there isn't room for future implementation, therefore Streams and its dependencies need to userand::rngs::StdRng
orrand::rngs::OsRng
instead. This is not a practical issue in the current scope of the PoC. See Github issue for more details.- ESP-IDF task watchdog must be deactivated, or increased an uninvestigated amount.
getrandom
does not yet supportespidf
targets and requires an small patch. Likely to accept a PR once espidf targets make nightly or stable.- Stack size must be at least 32368 Bytes in order to function without risking stack overflows
- Currently Streams requires
std
for generating random keys and nonces.- Technically
rand::rngs::StdRng
orrand::rngs::OsRng
work inno_std
scenarios, provided thatgetrandom
supports the target. rand
is being used only when sending keyload and subscribe messages. Therefore, if those don't need to be sent, Streams can be used withoutstd
feature.
- Technically
chrono
has compatibility issues with this target, and will require a patch. Streams dependency overchrono
was a legacy and has been removed, thus no further investigation has been performed. All I can say at this moment is that it has to do withstruct tm
not includingtm_gmtoff
innewlib
variant oflibc
- opt-level 'z' does not work for some reason; the program freezes few seconds after starting, deterministically. Executable size is not much smaller than opt-level 's' anyhow.
See memory usage output.
See runtime output.
- espressif/rust-esp32-example: boilerplate used for this PoC. Aparently the initial integration project
- ivmarkov/rust-esp32-std-hello: Alternative, pure-Rust example integration. Pending to be tested
- esp-rs: "The esp-rs organization has been formed to develop runtime, pac and hal crates for the Espressif chips (bare-metal as well as ESP-IDF based)"
- esp-rs/rust: Rust fork
- espressif/llvm-project: LLVM fork
- rust-lang/rust#87666: PR to merge libstd fork upstream. Merged 12-08-2021
- rust-lang/libc#2310: PR to merge libc fork upstream. Merged 3-08-2021
./scripts/docker/compile.sh && ./scripts/docker/run-qemu.sh
Rust source code is in components/rustlib
. Main function is in main/main.c
. C lib is in components/clib
.
- Test complete flow with SingleBranching
- Fix issues in subscriber to test the complete flow
- Test in real ESP32 device
- Test agaist Tangle using
client
feature