Code Monkey home page Code Monkey logo

colmeia's Introduction

colmeia


Hive (in portuguese). Attempt to make an interop layer to connect to dat on hyperswarm and legacy infra as well. Vaporware and might never be finished. Contributions welcome.

Goals

Write a pure rust network stack compatible with dat, to be able to run it on desktop (Win/Mac/Linux), mobile (and maybe wasm).

Milestones

  • Generate a binary that finds and talk to a LAN dat node: handshake and disconnect
  • Compile to Android
  • next Create a connection pool that tracks dat peers, and track hypercore version to allow crossing bridges
  • Bundle the static library into a Flutter app (validated as viable already with dat (legacy)) that displays the connection pool of dat peers for a given dat url (needs work)
  • (strech goal) Support routers (MIPS)
  • (stretch goal) validated as viable already with dat (legacy) Write a Flutter app (micro-app as in a micro-service) that syncs and share files, allowing to build other local-first apps without needing to bundle the network stack logic (like dat-desktop but for mobile and desktop without Node)
  • (stretch-er goal) WASM and websocket integration
  • (stretch-er goal) validated as viable already with dat (legacy) FFI bindings to be able to link into an iOS app and other languages (neon?/helix?/dart ffi?).

References

Uses NOISE protocol and a different handshake.

Modules

Discovery

  • colmeia-hyperswarm-mdns: Support to hyperswarm mdns infrastructure: based on hyperswarm/discovery
    • Locator: stream to find dat members in the network
    • Announcer: stream that announces a dat in the network
    • Mdns: announces and find dat in the network
    • Tests
    • All protocol 1:1
  • colmeia-dht: Interop with hypwerswarm dht infrastructure (:eyes: https://github.com/mattsse/hyperswarm-dht)
    • Tests
    • All protocol 1:1

Protocol

  • wip colmeia-hypercore: Networked module for hypercore storage
    • Hypercore replicate logic
    • Tests
    • All protocol 1:1
  • wip colmeia-hyperdrive: Networked implementation of content and metadata hypercore's
    • Hyperdrive: Use metadata to clone content hypercore feed (first block is content public key)
    • In memory
    • Write to disk
    • Impl remaining replicate logic for Hyperdrives
    • Tests
    • All protocol 1:1
  • wip colmeia-hyperstack: Discovery integration of hyperdrives
    • Create a Hypercore struct that discovers and creates peeredfeed interactions
    • Tests

Reference tools

Versions for reference

CLI binaries

Local dat2: be41e3d43d054982e14dfc60281d9d4425ab5d4b0b280a355b7927869ca08fc5

Find a local peer

colmeia-mdns

RUST_LOG=debug cargo run --bin colmeia-hyperswarm-mdns -- 7e5998407b3d9dbb94db21ff50ad6f1b1d2c79e476fbaf9856c342eb4382e7f5 8000

Connect and troubleshoot a peer

colmeia-nc

RUST_LOG=debug cargo run --bin colmeia-nc -- 7e5998407b3d9dbb94db21ff50ad6f1b1d2c79e476fbaf9856c342eb4382e7f5 127.0.0.1:3282

Clone from a single host

RUST_LOG=debug cargo run --bin colmeia-clone -- 192.168.15.173:3282 dat://6268b99fbacacea49c6bc3d4776b606db2aeadb3fa831342ba9f70d55c98929f

Platforms

⚠️ TODO: redo support as part of dat -> hypercore migration

Android Direct compilation

  • No root required

Inside termux, install git and rust:

apk install git
apk install rust
git clone https://github.com/bltavares/colmeia
cd colmeia

cargo run # your desired bin

Cross Compilation

It works!

  • No root required

  • Windows: Using WSL2 (windows insider) allows you to use Docker from WSL. Follow this guide to enable docker

  • Mac/Linux: It should just need to have docker configured properly

  • Install cross

  • Cross compile to your target:

cross build --target armv7-linux-androideabi
  • To find the correct target for your device: adb shell uname -m
arch target
armv7l armv7-linux-androideabi
aarch64 or arm64 aarch64-linux-android
arm* arm-linux-androideabi
mips-musl mips-unknown-linux-musl

*arm: (seems to be broken)

  • Push to Android on a writeable location. Android does not allow binaries to be executed from the /sdcard:
# Once
adb shell mkdir -p /data/local/tmp/colmeia
adb shell chmod 777 /data/local/tmp/colmeia # Make it readable to let Termux read it as well

adb push ./target/armv7-linux-androideabi/debug/colmeia-mdns /data/local/tmp/colmeia

Android ADB shell

adb shell # open shell in android
chmod +x /data/local/tmp/colmeia/colmeia-server

RUST_LOG=debug  /data/local/tmp/colmeia/colmeia-server 0.0.0.0:8787 dat://460f04cf12c3b9833e5a0d3dd8eea05eab59dd8c1438a7454afe9630b9b4f8bd

Termux from inside Android

Android don't allow execution from outside the app data dir, and you can't push data to other apps dir from adb push. You need to copy the binary to your root folder, which should be executable.

Open the app and copy the content to the home folder:

# Inside termux shell
cp /data/local/tmp/colmeia/colmeia-server ~

RUST_LOG=debug ~/colmeia-server 0.0.0.0:8787 dat://460f04cf12c3b9833e5a0d3dd8eea05eab59dd8c1438a7454afe9630b9b4f8bd

OpenWRT

It compiles with OpenWRT. Tested with 2 different routers on 18.06.1 and 19.07.2.

Run and scp the binaries on target/mips-unknown-linux-musl:

 cross build --target mips-unknown-linux-musl

colmeia's People

Contributors

bltavares avatar evaporei avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

colmeia's Issues

Discovery: mdns hyperswarm discovery

Livestream Details
Planned date Sunday 10am GMT-3 - 2020-06-07 in pt-br
Link https://twitch.tv/bltavares_codes
Timezone https://everytimezone.com/s/4eb77945

Goal

Start a new Beaker Browser 1.0 share on the computer, and find shared folder over mDNS message broadcast.

What we gonna do on the live stream?

This goal can be divided in two sub-goals: One to "Find Hyperdrives over LAN" and another to "Announce a Hyperdrive over LAN". This is similar to colmeia-dat1-mdns, but with a new protocol and data exchange.

We'll start with locating a Hyperdrive, and if we have time, announce our own hyperdrive as well.

Locate a Hyperdrive share

  • Find the packets on the network using Wireshark
  • Create a new UDP Socket in Rust that listen and broadcast mDNS packets
  • Query the network using mDNS packets
  • Create two async process: One to query, one to listen
  • Parse Beaker packets and print the information received
  • Expose a stream of IPs collected
  • Deal with errors instead of crashing with unwrap/expect's

Announce a Hyperdrive share

  • Find the packets on the network using Wireshark
  • Create a new UDP Socket in Rust that listen and broadcast mDNS packets
  • Listen to Beaker mDNS queries and print them
  • Create two async process: One to announce, one to respond
  • Respond with a well formatted query and check if Beaker tries to connect
  • Deal with errors instead of crashing with unwrap/expect's

References

Remove all unwrap and expects and add error handling

Nowadays, colmeia-sync and ffi panics when it tries to talk to itself, when the socket closes and the writer fails.

It would be nice to remove all unwraps and expect and change signatures to return errors as needed.

Ideally, ProtocolEvents should have a associated error type to allow use of other errors by the consumer of the trait.

Avoid locking on read from network

Some places have self.stream_on_network.write().next().await which may lead to locking the stream for a long time.

Some places use .timeout from async-std to avoid locking it for too long, but the timeout is arbitrary. Instead, it would be better to use .now_or_never() from future crate.

This would make it easier to use also make the executor abstract on #25

Handle discovery of multiple feeds

Currently, colmeia has been working with as single hypercore concept.

@Frando has been very kind to share some of his early work on his hypercore-replicator crate, which the design supports replicating multiple feeds.

Hyperdrive, the filesystem abstraction built on top of hypercores, has to replicate at least 2 cores.
This is noticeable when debuging MDNS discovery messages where we receive multiple feeds at once.

This is also how JS is replicating the data. Now, there is a corestore and the hyperspace API in JS, which is this broader abstraction of maintaining multiple feeds in sync at once.

To align better with @Frando's hypercore-replicator, which is a quite nice API, this issue documents the need to change how Colmeia deals with single feeds vs multiple feeds.

Concern

Currently, to replicate and discover multiple hypercores in colmeia, it would need to create multiple Hypercore Stacks (as on #21), which means opening multiple sockets at once. That means that each hyperdrives (pairs of cores) would allocate one listener socket, one discovery mdns responder socket and one mdns discovery. Given we are targeting mobile (and possibly routers), that is a bit wasteful.

It would better fit to redesign colmeia-hyperswarm-mdns to be able to add new feed keys (and removal), so we can discover multiple feeds on the network with a single socket.

Make task executor configurable

Currently, this libraries since #21 has been using async-std to spawn new tasks.

We could instead offer the task executor to be configurable using cargo feature selectors. There is the https://github.com/bastion-rs/agnostik crate to help with this.

This would let the code to be also used on Tokio or Bastions codebases (preferring using async-std or smol by default, given that we still make use of async-std::RwLock on other stuff.

I have no idea what a proactive IO framework is as well - but it would be worth checking if it make sense to use (https://github.com/vertexclique/nuclei)

Given that colmeia-hyperswarm-mdns crate is using my own custon multicast-socket crate, it would not benefit from async-std's epoll io or bastion-rs/nuclei. The replicator crate would be the next one that need to find a good io replicator.

TODO on a livestream:

  • Include bastions-rs/agnostik crate on every crate that spawns tasks
  • Add feature selector to select which crate to use

Investigation:

Discovery: MDNS does not find devices across multiple interfaces

I found that running the discovery on mdns only worked for one interface. As soon as I tried it on a multihomed device, such as my laptop with WiFi and Cable on different networks, I could not find it anymore.

The discovery has been documented on socket-2, which shows that while we can listen on multiple interfaces for the incoming packets, we need to do some gymnastics to send packets on multiple interfaces.

Goal

Create a single socket which listen to multicast packets on multiple interfaces, and can send packets on a multiple interfaces as well.

What we gonna do on the live stream?

The goal is to create a socket interacting with socket-2 that provides an API to multiple interfaces. This will require having Rust interact with C++/C structs and do C->Rust FFI (which I have no idea how to do that much.) Come learn with me.

Create a Multicast UDP socket that:

  • Listens for a specific multicast ip:port (eg: MDNS)
  • Join multicast group on multiple interfaces
  • Receive a message: (data, origin ip, origin interface)
  • Send a message: (data, destination ip, origin interface)
  • Send a message on all active interfaces: (data, destination ip, [all interfaces])

References

Move from Dat Protocol to Hyperdrive Protocol

Dat Protocol is moving into a new version, that is not backward-compatible.

To help to communicate this breaking change Dat announced it is moving to Hypercore Protocol.

Dat (also known as dat1 on this repo) will keep existing as is, but the same team that maintained the protocol (also known as dat2 on this repo) is now focused on adding features only on the new protocol.

Also, the new Beaker only works on the new protocol, and will migrate the library on previous Dat to Hypercore.

Apps that were targeting Dat will not work with the new protocol, as discovery also changed.

This is tracking issue to move colmeia to the Hypercore Protocol:

  • Discovery: mdns hyperswarm discovery #11
    • Fix multi-interface discovery #15
  • Handshake & Exchange with hypercore protocol over network #18
  • Update hypercore version used on the code to the beta releases #21
  • Change https://github.com/bltavares/parse-dat-url to parse-hyper-url #21
  • Move dat bins to hypercore protocol #21
    • All dat bins moved into legacy for historical purpose
    • All previous bins available as hypercore
  • Move dat1 from the repo to avoid dependencies breaking the latest code

Provide `hypercore-nc` binary

Livestream Details
Planned date Sunday 10am GMT-3 - 2020-07-12 in pt-br
Link https://twitch.tv/bltavares_codes
Tracking #10

Now that we have multicast, I would like to be able to interact with the beaker we found on the network.
We can test this by creating a new binary similar to colmeia-nc but using hypercore instead of dat.

So we will:

async-std not found on compilation

Hey! Nice project by the way 🙂

So I've being trying to compile it and having trouble on it.

I've tried just cloning and using cargo build but I get this output:

╭─otaviopace at mettaton in /Users/otaviopace/colmeia (master ✔)
╰─λ cargo build                                                                                                                cross-0 | 101 < 02:11:17
    Updating git repository `https://github.com/async-std/async-std`
error: failed to resolve patches for `https://github.com/rust-lang/crates.io-index`

Caused by:
  failed to load source for dependency `async-std`

Caused by:
  Unable to update https://github.com/async-std/async-std?branch=fix-atomic-32#64844deb

Caused by:
  revspec '64844debcb15dc8e7fd2340577da24dbcaeb781a' not found; class=Reference (4); code=NotFound (-3)

After reading some of your README.md, I've seen that you use cross to compile for Android. So I've tried using it too to compile, and I had the same issue 🤔

╭─otaviopace at mettaton in /Users/otaviopace/colmeia (master ✔)
╰─λ cross build --target armv7-linux-androideabi                                                                                  fish-0 | 0 < 02:10:27
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
info: latest update on 2020-06-04, rust version 1.44.0 (49cae5576 2020-06-01)
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-docs'
info: downloading component 'rust-std'
info: downloading component 'rustc'
 60.2 MiB /  60.2 MiB (100 %)  50.6 MiB/s in  1s ETA:  0s
info: downloading component 'rustfmt'
info: installing component 'cargo'
info: installing component 'clippy'
info: installing component 'rust-docs'
 12.2 MiB /  12.2 MiB (100 %)   8.6 MiB/s in  1s ETA:  0s
info: installing component 'rust-std'
info: installing component 'rustc'
 60.2 MiB /  60.2 MiB (100 %)  15.0 MiB/s in  4s ETA:  0s
info: installing component 'rustfmt'

  stable-x86_64-unknown-linux-gnu installed - (error reading rustc version)

info: checking for self-updates
info: downloading component 'rust-std' for 'armv7-linux-androideabi'
info: installing component 'rust-std' for 'armv7-linux-androideabi'
Unable to find image 'rustembedded/cross:armv7-linux-androideabi-0.2.0' locally
armv7-linux-androideabi-0.2.0: Pulling from rustembedded/cross
fe703b657a32: Pull complete
f9df1fafd224: Pull complete
a645a4b887f9: Pull complete
57db7fe0b522: Pull complete
c3de58f51717: Pull complete
f8aac8546953: Pull complete
e0fe7a974cca: Pull complete
de899c6f7dca: Pull complete
abf70cb17661: Pull complete
f707b04b4965: Pull complete
3b162ba5b74b: Pull complete
67d0daeca688: Pull complete
c2de46407807: Pull complete
fa889352c751: Pull complete
c1779a84f287: Pull complete
72a6883f1f42: Pull complete
2d3e8798ffc5: Pull complete
Digest: sha256:853737710515f5de9a1442676c38065fc1f6dcd3f57904ee10f63814c70661a8
Status: Downloaded newer image for rustembedded/cross:armv7-linux-androideabi-0.2.0
    Updating git repository `https://github.com/async-std/async-std`
error: failed to resolve patches for `https://github.com/rust-lang/crates.io-index`

Caused by:
  failed to load source for dependency `async-std`

Caused by:
  Unable to update https://github.com/async-std/async-std?branch=fix-atomic-32#64844deb

Caused by:
  revspec '64844debcb15dc8e7fd2340577da24dbcaeb781a' not found; class=Reference (4); code=NotFound (-3)

So I have two questions:

  • Do I have to do some kind of change on my Rust installation to async-std actually work on my computer?
  • Does your project work compiling just for Windows/Mac/Linux, or everytime you do changes you have to use the cross compilation?

By the way I had the same issue on MacOS and Linux, but the logs are all on a Mac machine. Here is my installation info:

╭─otaviopace at mettaton in /Users/otaviopace/colmeia (master ✔)
╰─λ rustup update                                                                                                               fish-0 | 101 < 02:13:17
info: syncing channel updates for 'stable-i686-pc-windows-gnu'
info: syncing channel updates for 'stable-x86_64-apple-darwin'
info: syncing channel updates for 'stable-x86_64-pc-windows-msvc'
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
info: syncing channel updates for 'nightly-x86_64-apple-darwin'
info: checking for self-updates

       stable-i686-pc-windows-gnu unchanged - (rustc does not exist)
       stable-x86_64-apple-darwin unchanged - rustc 1.44.0 (49cae5576 2020-06-01)
    stable-x86_64-pc-windows-msvc unchanged - (rustc does not exist)
  stable-x86_64-unknown-linux-gnu unchanged - (error reading rustc version)
      nightly-x86_64-apple-darwin unchanged - rustc 1.46.0-nightly (118b50524 2020-06-06)

info: cleaning up downloads & tmp directories

Cleanup the code

What are the opportunities to improve the code?

I would like to start adding tests now that I'm able to connect to dat's and validate the design as we go.

There are lots of clone. Is there any chance to reduce memory allocation?

Replicate multiple feeds on a single colmeiad instance

The colmeia-hyperdrive crate is conflating the storage, peering, hyperdrive and hypercore code.

With @Frando's upcoming hypercore-replicator, we should be able to handle multiple replicated feeds, and we can focus on writing only the hyperdrive code, without conflating that much.

TODO Next livestream:

  • Split colmeia-hypercore into colmeia-hyperdrive, and only use hyperdrive code.
  • Adopt hypercore-replicator from @Frando on hyperstack
  • Adopt updated hyperstack on colmeiad
  • Bonus: Change protobuf crate to use the same as hypercore protocol (reduce dependencies) PROST depends on protoc

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.