# Spimpl
This note explains the problem that Spimpl (a simple implementation of [The Portal Network](https://github.com/ethereum/portal-network-specs) ) tries to solve and lists the efforts already made to "prove the concepts." While you may not agree that the problem is a vital one and the solution is justifying, it's my belief that the work could contribute to offering better user experiences for mobile devices -- faster syncing, less energy consumption, and improved mobility handling.
## Sockets 2.0
### Problem
For the last few decades, sockets and the socket API are what we have been using for network programming.
#### Unavoidable memory copying from kernel to user process
Transport protocols such as TCP/IP live in the kernel, and the remaining protocols (HTTP, TLS, etc.) are handled in apps. When you switch between the two, memory copying happens.

A picture from my copy of the book "TCP/IP Illustrated, Vol. 1: The Protocols", the first edition by W. Richard Stevens, with the involved part circled in red.
#### Mobility can be a challenge with sockets
Today's mobile devices in our pockets often have multiple radios that may be on at the same time, and network switching is not uncommon. While it may be too early for us to bring this issue to the table, we should keep it in mind -- a (mobile) light client has to handle such network transitions well to provide a pleasing experience to customers on the go. As far as I know, sockets does nothing to help you with this.
### Solution
Modern alternatives to sockets have been emerging.
For Linux/Android, we have io_uring.
For macOS/iOS, we have [Network Framework](https://developer.apple.com/documentation/network?language=objc).
Both io_uring and Network Framework support "User-Space networking" (or zero-copy I/O). Network Framework also offers functionality to help you handle mobility.

An Apple engineer giving a demo shows ~30% less overhead. Source: [WWDC 2018 session 715](https://developer.apple.com/videos/play/wwdc2018/715/), starting at 48:00
## Why libdispatch
Grand Central Dispatch (libdispatch) is a (concurrency) task system. It's mainly supported by [macOS/iOS](https://developer.apple.com/documentation/dispatch?language=objc) and is also available on [Linux/Android](https://github.com/apple/swift-corelibs-libdispatch/).
- libdispatch is a [pretty good](https://youtu.be/QIHy8pXbneI?t=1860) task system.
- Network Framework already uses libdispatch in its implementation and API.
- It's open source and available on [Linux/Android](https://github.com/apple/swift-corelibs-libdispatch/).
- libdispatch enables "no raw synchronization primitives" to some extent. [example1](https://www.youtube.com/watch?v=zULU6Hhp42w&t=3327s), [example2](https://youtu.be/zULU6Hhp42w?t=1084)
### Memo
#### Attaching one specific thread to a queue
The design of libdispatch intentionally removed the concept of "thread". But occasionally, we may want to have a queue attached to one specific thread. One example is to work with third-party libraries that expose API with thread handles. Newer versions of libdispatch now support [running a queue on a single thread](https://developer.apple.com/videos/play/wwdc2017/706/) (starting at 30:46). In case we need this feature, we know it's achievable with libdispatch.
### Why not Tokio
#### Introduction
[Tokio](https://tokio.rs) is a popular asynchronous Rust runtime. It offers efficient non-blocking (sockets-based) TCP and UDP functionality. Such efficiency is achieved by leveraging the operating-system's evented I/O API (epoll, kqueue, etc.). Many projects rely on Tokio for networking. Here are some of the projects that use Tokio: [Rust implementation of Discovery v5](https://github.com/sigp/discv5), [NTP implementation in Rust](https://github.com/memorysafety/ntpd-rs), and [an implementation of IPFS](https://github.com/n0-computer/iroh).
#### Modern sockets
Modern sockets alternatives are asynchronous by default. We should now be able to complete an efficient implementation without leveraging an asynchronous runtime such as Tokio.
#### Cannot we integrate io_uring and Network Framework to Tokio
[Tokio + io_uring](https://github.com/tokio-rs/tokio-uring) is being developed, but it's still young. For Network Framework, there probably will never have one.
Assuming Tokio supports both, getting Tokio involved increases complexity.
## Prerequisites
Efforts I made to "prove the concepts".
### Accessing Network Framework in Rust
[nf_netcat](https://github.com/weipin/nf_netcat), a Rust port of netcat. This project aims to demonstrate that it's achievable to create a networking program in Rust with Network Framework.
### "Wallet Core" library
[lightcryptotools](https://github.com/weipin/lightcryptotools), a dependency-free Rust library provides fundamental functions for crypto(currency) wallets.
### Another ENR implementation
[simple_enr](https://github.com/weipin/simple_enr), an Ethereum Node Records Rust implementation. It provides a simple identity scheme abstraction and could be [a little bit faster](https://github.com/weipin/simple_enr/blob/main/benches/enr_decoding.rs).
### Byproducts: bugs discovered
Bugs discovered during the research phase:
- getrandom (low-level Rust API): Error checking on iOS for `SecRandomCopyBytes` [#243](https://github.com/rust-random/getrandom/issues/243)
- enr (Rust ENR implementation): [RLP] Refactor integer decoding [#7](https://github.com/sigp/enr/pull/7)
- enr: Adds entropy to secp256k1 signatures [#5](https://github.com/sigp/enr/pull/5) (this obviously isn't a bug, but my attempt to make the number to three, if I may)