Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mock UI - Lorem Ipsum #1

Open
9 tasks
karalabe opened this issue Mar 17, 2020 · 28 comments
Open
9 tasks

Mock UI - Lorem Ipsum #1

karalabe opened this issue Mar 17, 2020 · 28 comments
Labels
area:ui User interface work

Comments

@karalabe
Copy link
Member

karalabe commented Mar 17, 2020

This is a tracking issue for defining the minimum requirements and mock UI for the app to be useful.

Mock screens (you can switch between these by commenting out various "Screen" components at https://github.com/coronanet/rn-coronanet/blob/master/App.js#L21):

  • Welcome screen (Mock UI - Welcome Screen #4)
  • Registration screen
  • Dashboard screen: News feed
  • Dashboard screen: Contact list
  • Dashboard screen: Event list
  • Dashboard screen: Change status dialog
  • Dashboard screen: Add contact dialog
  • Dashboard screen: Create event dialog
  • Dashboard screen: Join event dialog

The state of the mock UI as of March 15, 2020 is:

coronanet

@karalabe karalabe added this to the Phase 0: Mock UI milestone Mar 17, 2020
@karalabe karalabe added area:ui User interface work and removed phase:mock-ui labels Mar 17, 2020
@daodesigner
Copy link
Contributor

First draft at an (almost full) UX mock up for Corona Network: https://www.figma.com/proto/grE1s3BT52wNz1iB1hKJ4i/Corona-Network?node-id=3%3A277&viewport=262%2C662%2C0.25607821345329285&scaling=min-zoom

Removed some features in favor of a simple and familiar UX for MVP.
image

image

@karalabe
Copy link
Member Author

karalabe commented Mar 18, 2020

Thank you so so much in putting all that work in :)

I may have to shoot a few features down though due to the way the tech I envisioned would work, but would be happy to be proven wrong.

The direction I'd like to push this project towards is to be completely decentralized (no cloud, no server). Technically/practically, that would mean that it's based on Tor circuits and Onion services (I don't want to either reinvent the wheel, nor start inventing a new P2P protocol). This has a few implications however.

User identity in this setup would simply be a private key. We in theory could attach some extra information to it (social logins), but I'm unsure what the value would be in the first incarnation. That's why I originally only added a name (avatar is a nice touch, virus status and status message are also probably needed, but not sure if we need anything else). Your mobile device would generate you your key the first time you "create an account" and they you just run with it. In the first incarnation I wouldn't even support logging out or porting your user to a different device, just simply "nuke my account" if you don't want to use it any more.

Moving your account and data to another device or supporting login/logout is a fairly large can of worms. I have a prototype that does something like that (it scatters your data among your friends, who can feed it back to you on a different session/device). It's a very nice challenge, but finalizing that would be a lot of work with very little immediate gain for an MVP. As such, I think user handling should mostly boil down to "Create new user" (which under the hood generates a private key), and "Nuke my user" (which simply deletes all your local data).


The second nut I'm unsure how we could crack is GPS and maps. The problem at short is that map access requires a map provider. That's super expensive. Google maps gives you some 1K or 10K free loads per day, but if you exceed that, they charge you crazy money. Since this app would not be monetized, there's no place to cover such things from.

The decentralized approach also kind of rules out hosting a tile server ourselves, since I would really like this app to not depend on 3rd party infra (ok, it will depend on Tor, can't work around that any time soon). The only kind of possible path I could see if we either bake in some maps into the app itself (I don't think we can cram a meaningful resolution into it), or if we can download it from a place that guaranteed keeps it available forever (openstreemap has torrents, but not on demand regions afaik).

Curious if you know of a solution that we could use here?


Regarding MVP UI/UX features, my original idea was for the app to be able to tell me if I run the risk of being infected. For this, we need to be able to define some notion of "contact between people". Since we can't do geographical contact detection without some centralized tracking (and we don't want to share our location with the world), I was trying to figure out an alternative definition of "shared location".

The idea I came up with is "an event" (e.g. "movie night at someone's place", "ethcc conference", "a theater show"). Such events would always have an organizer (e.g. me, gnosis, the state theater). The same way each person is represented by a private key, each event would be essentially the same, a private key running a Tor onion service (hosted by the organizer's device). Everyone could "check in" to these events on arrival via a QR code, similar to how they can "friend" each other. This checking-in creates a virtual contact and timestamp between all the participants, and it also establishes a communication channel (the event onion service) between them. After X weeks, the event is deleted (onion torn down).

An future extension of the "event" could be a "location" (e.g. theater, park, venue). Again, an operator would need to "run" these locations, hosting the onion service. This would allow anyone visiting to "check in" (scan qr code), and report back infections. Since the "event" or "location" maintains a communication channel between all visitors, the infection report can immediately be propagated to all relevant visitors.

What the above "event" and "location" would allow us to do is to redefine the notion of "contact between people" from a "contiguous coordinate in the real world that's super sensitive to share + a global all-powerful operator with access to all data" to an "abstract private key that's un-guessable and will be irreversibly destroyed in 2 weeks + local operator (event organizer) with access to 2 weeks of data from a limited subset of people".

Essentially, just by shipping support for the "events", we can already create an almost fully untrusted temporal and spacial link between people, that allows them to communicate even if they don't all know each other; and it also allows algorithms to automatically provide infection risk guesses based on the announces.

This was my original dream for an MVP: Let me responsibly track the people I care about and events I attend; and let the program do the dirty work of linking everything together to warn me about dangers :)

@daodesigner
Copy link
Contributor

daodesigner commented Mar 19, 2020

Thank you for clearing up a few things have a better picture of what you want to get done.

Made changes to minimize data/UI, got rid of the map dependency in favor of a practical but less precise heat-map.

To take care of privacy concern, we can blur the GPS resolution by rounding long/lat to the minutes resolution (around 1 mile blocks effectively), the events paradigm I think is over engineering the solution, endangers who ever the host is, and sends the wrong message. I propose:

Each key/phone broadcasts all it's signed virus statuses and truncated GPS coordinates from 1st degree contacts (no personal information from contacts however) within 15 miles of person requesting along with their own profile data. Phones store the data they receive if it's within a 15 mile radius locally in something like a CRDT to give us consistency over the data regardless of how it propagates.

This allows for an untrusted temporal and spacial link between people even if they don't all know each other and covers a picture of what your city looks like (< 90% of cities are under 30 mi^2). and a little more color for the people that you do know.

image

Prototype:
https://www.figma.com/proto/CX6fnvDE6Vyo9EM7BA57wA/Corona-Network-MVP?node-id=67%3A6794&viewport=-87%2C-14%2C0.1633376032114029&scaling=min-zoom

@karalabe
Copy link
Member Author

Each key/phone broadcasts all it's signed virus statuses and truncated GPS coordinates from 1st degree contacts (no personal information from contacts however) within 15 miles of person requesting along with their own profile data. Phones store the data they receive if it's within a 15 mile radius locally in something like a CRDT to give us consistency over the data regardless of how it propagates.

I guess the hard technical question is how? Without a central operator that collects, filters and feeds the data back to you, how can phones nearby ind each other? This is what I haven't figured out. If there would be an easy way to for example use bluetooth without pairing or some such thing, there's a lot of nice things that could be done.

Otherwise I agree that this generic solution would be much nicer than the manual checkin.

@daodesigner
Copy link
Contributor

daodesigner commented Mar 19, 2020 via email

@karalabe
Copy link
Member Author

All this said, perhaps it'd be worthwhile to have a DB if only for the
non-personal data. If the app hits critical mass might have better national
risk estimates than CDC lagged testing.

I can't go down that path:

  • Running a central service where everybody pops in or reports data to would be a huge maintenance burden and also a cost burden. If the app were to hit critical mass, that would become very nasty very fast.
  • The moment I begin to store any data centrally, I'm entering "privacy policy" territory, we'd need to explain where and how and what data is stored. In Europe storing any data means that all of a sudden GDPR becomes in effect, so people must be able to request it from you and request that it be deleted, which is a huge admin overhead. In my country to store "personal" data, the state already defines some bare minimum criteria that they can audit you for; I'd guess anything even remotely resembling medical stuff would be a huge red flag.
  • I think the value of a real time updating database of infections + even approximate coordinates would be too juicy of a target to be hacked or subpoena-d. I don't want to either be responsible for that nor enable it.
  • I think people would be much more willing to share their medical status if they know only ever they friends or direct contacts get notified, but it does not go into any central system and cannot be retained. Centralizing even some data will have a chilling effect.
  • I have a personal challenge for myself to demonstrate that you can make a socially useful and meaningful application without centralizing access. I want to show the world that the Google, Facebook, etc model is inherently flawed and is not a technical limitation why they do it like this, but a monetary one.

Now that that's out of the way :D, a few notes on the graph approach:

  • At the end of the day, the base of your graph is exactly the same as the contact list of my idea: each person is a vertex, and you can make a link between them by scanning a QR code. The QR code is essentially an onion URL + some metadata and maybe authentication things, so it can easily be represented by a link that you can share out of the app too.
  • I'm a bit on the fence of posting such "links" to social media (or anywhere really) as I think its too sensitive information (i.e someone who finds you link you access your data). I thought about them more like "bluetooth pairing", where you create your link and the other side has a limited amount of time to pair up (e.g. until your "pairing" screen is kept open).
  • Once you have this graph you could indeed shuffle around location data, but I'm unsure about the privacy implications. At the end of the day, devices need to figure out that they had a contact with some other device.
    • My issue with any geographical approach is that you need to have access to someone's entire location history (positions and timestamps) to be able to tell if you were close to them or not. This seems like a privacy dead end. Even if we only share rough coordinates, if you have access to the entire timeline, it still leaks out too much info.
    • It would also be a data propagation issue because everyone would need to crunch through a lot of other people's data to see if it's relevant for them or not.
    • The only semi-realistic way I could see this work is if we could somehow tap into the bluetooth systems of the phones and use them as some sort of proximity detectors. That however seems like a violation of the bluetooth protocol, since you should only be able to communicate when paired. Also a lot of phones have bluetooth turned off, and I don't think it's realistic to assume people will start walking around with bluetooth enabled just for this.

All in all I do agree that some automatic proximity detection would be desirable over manual checkins, just not sure how that could work out in practice. I would either way want to forcefully bind it to the physical world (bluetooth, direct connection, scan qr code locally), otherwise we'd run the risk of someone willing the system with fake data.

@karalabe
Copy link
Member Author

Tiny update:

This looks really promising. I need to finish up the Tor integrations into the backend first (pulled in my Tor P2P code yesterday) and need to create an easy way to pair nodes, but hopefully I can do that today and maybe I can dig into the bluetooth tomorrow.

@daodesigner
Copy link
Contributor

Ok made UI to match your spec more closely. At this point I think perfection is the enemy of progress I want to ship something in the next two weeks, I am happy to commit to implementing this with your backend if we can agree.
Let me know what you think of the mocks think we're at a last round of feedback before adding details and starting to implement the rn app.

image

https://www.figma.com/proto/y3VSBxXOrX6f6tCeHFF7HB/Corona-Net?node-id=1%3A4438&viewport=-346%2C2816%2C0.4470480978488922&scaling=min-zoom

@karalabe
Copy link
Member Author

Sorry if I've been a bit unresponsive on this thread. I was trying to push through a PoC backend that can be used to serve at least some meaningful data across the entire stack so that we can verify that the base idea itself works before putting too much time into it. It's a non-trivial amount of work to push the entire stack through though:

There are still a couple steps missing until there's an entire workable flow crossing over from one phone to another:

  • The backend is non existent yet. We have the REST api specced that comes from atop, and we have the P2P networking that is below it. I just need to glue the two together + add some PoC functionality wrt profiles to allow testing.
  • I'm currently working on some minimal Postman tests to verify that the REST actually does what it says it does so that there would be no surprises n the UI.

Working on this as fast as I can :)

@daodesigner
Copy link
Contributor

daodesigner commented Mar 23, 2020

Ok. So I took this weekend to take a step back and read through all of github.com/ipsn/go-ghostbridge, github.com/ipsn/go-libtor, and github.com/coronanet/go-coronanet. It was a spiritual experience. HOLY SHIT. I mean just go-ghostbridge alone blows my mind, brilliant.

You are too humble, even with a fair probability that the project will flop you are closer to a mobile first, actually secure/private/decentralized social network than any project I've ever seen; you've essentially done so by your bloody self, and the code quality brings a tear to my eye- the love and creativity that's gone into it is palpable.

I have enough to go off to start an implementation/contribute more meaningfully now that I understand ghostbridge/go-libtor. I can contribute more meaningfully on the protocol side if you (want to?) make some of the things you mentioned above into issues to delegate (you clearly don't need to). I completely understand leaving out the open source license and honestly might advise you to just make the entire repo for corona-net private for the time being- you only really need to expose the gomobile outputs and swagger spec.

In any case happy to contribute in any way to make this a reality, even outside of Corona Network a lot of this is ground breaking on its own, will start developing the front end so that it's REST plug-able and ping back here in a week to see where we're at with the wire protocol.

@karalabe
Copy link
Member Author

😊

I've tried a few approaches before the current one. I originally wanted to go with IPFS + IPNS (hence where the InterPlanetary Social Network name comes from). I had an implementation for account management + mini things on top of them, but the whole thing just didn't work as I expected. IPNS is not reliable, IPFS is a resource monster. I've tried to patch is certain things, fix IPNS, but at the end of the day it was a dead end. That took months of my time.

Not sure how I stumbled upon Tor as a possible next approach. I wanted to see how far I could push the envelope. I wanted to use Go as I contributed to gomobile (yay my Ethereum Android client) a while back and knew it would solve running anything on Android. The question was whether it's possible to run Tor from Go, natively. Turned out that it's super perverted, but possible (yay my Ethereum USB library) so I ended up doing a "feasibility" study: https://medium.com/interplanetary-social-network/a-pinch-of-privacy-tor-from-within-go-fc4b09986120 I dropped the ball for quite a long time. It took way too much time to wrap Tor, it kind of worked, but also had issues. Just was exhausted.

A bit later I started experimenting with my libtor again, patched it up so it's more production-y, built some toys on top (https://medium.com/interplanetary-social-network/torfluxdb-anonymous-metrics-from-go-ce4f443e01fc). Got the motivation and started creating a mobile UI in React Native + a backend library. The whole thing just blew up. Crossing from RN to native modules to java to c to go was insane. I've implemented quite a bit of bridge code and then I just gave up. It was such a horrible resulting code that I called it a dead end. Then came the epiphany with ghostbridge (https://medium.com/interplanetary-social-network/ghost-bridge-react-native-to-go-19a69473f8e). I was super happy, but after publishing yet again a whole open source project, I felt burned out of it, so I closed the lid on the effort.

Half a year later I've played with at least 3 variations of a file sharing app on Android, some directly via Tor, some via IPFS, some via IPFS + Tor + some JavaScript bridge. All ended up in the bin. Good learning experience, horrible waste of time. I realized I still don't have enough building blocks for my decentralized system. I had raw networking via Tor and I had "UI" via REST, but in between was too much to fill in one project. After again a lot of time I figured I could build more puzzle pieces, that's how I made tornet (included in go-coronanet). It was only a WIP PoC, was quite happy with the security and crypto (lost count how many "crpyto identities" I've implemented over 2 years for this, 5 at least), but it was a lot of effort and I couldn't motivate myself to dive into the "socail" network part (feeds, posts, profiles, etc).

Fast forward again half a year and we're here. I'm super enthusiastic about this project because I can write a few more puzzle pieces (profiles, contacts, ui), and this super limited social network would already be valuable; without having to go all out and compete with facebook. Also being super limited, there's a much much higher chance that this can work out (even if my long term dream not, or not yet). Last but not least it's a perfect feasibility study for continuing with my social network eventually or not.

As for keeping it closed. I've tried that. Originally the IPFS/IPNS work was closed, I had a forum with maybe 5 people on it, but I realized nobody will really help out if it's closed, so by keeping it away from the world I'm just leaving it to bit rot. I've never really published all my experiments, failed projects, etc, but every time I think I have a legit puzzle piece that is valuable, publishing it forces me to make it high enough quality. If I get a few contribs out of it too, it's already more valuable to me too than it was closed.

I'm also so so very happy that you're spending your time helping build this. It's such a huge boost to motivation that I'm not alone with my toys. So even if things don't work out thank you.

Anyway, enough of the philosophy :)


I've finished pairing today, the entire end-to-end flow, so now contacts can "friend" each other. Yesterday I've fixed some issues in Tor and now the whole system startup/restart thing works, and I think all REST APIs wrt gateway handling, profile handling and pairing is good to go (most certainly there's room to improve, but hey, I've started this project 10 days ago :D (+2 years thinking about it)).

I've ran out of time today to finish the contact integration so that after pairing, the nodes actually start to chatter (they do connect not, just crash because I have a nil handler :P). Will try to fill in the missing things tomorrow, and hopefully by evening I can make a v0.0.3 .aar that will have full contact management and profile/avatar sharing working. That would be a huge cornerstone for me because that's the first version where the entire system / tech stack as a whole ticks, together. The rest is just adding bells and whistles.

My only concern now is what will the bandwidth / battery cost of the system be. This is the true test that the PoC will answer. If it's decent, we're golden.

@karalabe
Copy link
Member Author

It works :) Decentralized social network is online :) Will make some polishes tonight, and push a new release on the Go repo.

coronanet/go-coronanet#20

@0mkara
Copy link
Contributor

0mkara commented Mar 24, 2020

Let me know how to hook up the UI with backend.

@daodesigner
Copy link
Contributor

daodesigner commented Mar 24, 2020 via email

@karalabe
Copy link
Member Author

karalabe commented Mar 24, 2020

Just published v0.0.3 of the backend https://github.com/coronanet/go-coronanet/releases/tag/v0.0.3, I've also spent quite a bit of time to write up a short summary of the endpoints (details in the REST spec) and the pairing workflow. Hope this makes things clearer.

@daodesigner The Ubuntu version shouldn't really matter (I think I'm on latest released). Building it will require a stock gcc (whatever, we don't care) and a fairly recent Go (if you're unfamiliar with Go flows, installing via snap may be the easiest).

EDIT: There's also a slight chance that Ghost Bridge won't work as is. I've never used it from an infinitely running background service before. It most definitely should support the model, but the I might need to add some Java code to correctly reinit the bridge on app restart. Will do it tomorrow, need some rest now.

@daodesigner
Copy link
Contributor

SO, got everything up and running and made a quick and dirty dash to test Ghost Bridge.
https://gph.is/g/EGgW5xd
Quick takeaways of what immediately stands out:

  • GhostBridge just works , it feels good to use and was able to get hooks up to QR code gen in the flow very quickly.
  • Some of the endpoints are finicky
    • /pairing GET,POST seems to time out sometimes
    • /gateway DELETE fails (will try to pin down when)
  • Unit tests on RN side will be a B****
  • There is non-negligible lag (~800ms) for most endpoints but that might just be my emulator

will finish writing the react hooks today and push something up, at which point the UI is pretty much decoupled from the internal networking and can breakup the UX to divide and conquer, shooting to get another Android device today to continue with the pairing flows and hopefully have some of the UI cranked out by the end of the week.

@karalabe
Copy link
Member Author

Sweet :) Just made a small demo for @0mkara, but I guess that might be late :D

diff --git a/components/WelcomeScreen.js b/components/WelcomeScreen.js
index 98ce7bc..ad757fc 100644
--- a/components/WelcomeScreen.js
+++ b/components/WelcomeScreen.js
@@ -3,6 +3,17 @@ import { Layout, Text, Button } from '@ui-kitten/components';
 import { Dimensions, View, Image } from 'react-native';
 
 export const WelcomeScreen = ({ navigation }) => {
+  // Nuke any previous user, create one from scratch, start the gateway
+  fetch('https://corona-network/profile', {method: 'DELETE'})
+    .then(() => fetch('https://corona-network/profile', {method: 'POST'})
+      .then(() => fetch('https://corona-network/gateway', {method: 'PUT'})
+        .then(() => fetch('https://corona-network/gateway')
+          .then((response) => response.json())
+          .then((response) => alert(JSON.stringify(response)))
+        )
+      )
+    );
+
   const navigateSignup = () => {
     navigation.navigate('Signup');
   };

@daodesigner

/pairing GET,POST seems to time out sometimes

This might be due to the way it works internally (we can change the APIs to make it more meaningful/helpful to the UI). When you do POST /pairing, it generates a new temporary crypto identity (should be super fast) and opens a new onion service through Tor to listen on for incoming pairings. The issue you are probably seeing is that the call blocks until the onion becomes operational.

The idea behind blocking was to only give you back the shared secret after the onion service is online, otherwise you might end up with scanning a pairing QR code before there's anyone listening on the other side. I agree that this might be less than ideal. We could make it async so it gives you back the secret immediately and continues to build the channel in the background, but then we need a way to notify if it fails for whatever reason.

GET

Are you sure it's GET that is slow and not PUT? PUT does the same thing on the other side: it needs to do a network connection to your original onion. Until that is done, your local GET cannot return either, because it's waiting for the pairer to join.

/gateway DELETE fails (will try to pin down when)

This is an odd one as it should just tell Tor to disconnect and not even wait for it. Either way, I do propagate any error back in the response body, so that might help see what's odd.

Unit tests on RN side will be a B****

Oh yes. I'm trying to make a testable binary Go side so that we can do all the scenario testing there (perhaps even the REST endpoint tests) and minimize the crossover tests that's needed in RN.

There is non-negligible lag (~800ms) for most endpoints but that might just be my emulator

It's hard to pinpoint hat might be off in the general case. Some endpoints wait for networking (understandably slow), some do crypto (shouldn't be too slow). If you have specific problematic endpoints, I can def take a look. The baseline should be GET /profile or avatar or contact. Those just do a tiny db read and return it. If those are slow too, there might be something odd going on.

@karalabe
Copy link
Member Author

Dived into reworking my old tornet PoC package. The old one worked, but I've learned a few things about Tor and bandwidth usage that caused be to reevaluate the model a bit. Instead of going with an Ethereum-style P2P networking where there's a constant chatter, I'll go with a silent-unless-must-speak model. That should help drastically reduce bandwidth and battery drain. It'll probably take me a few days (not too much free time) to rewrite the entire thing, but as a first step I reevaluated the crypto identities I was using and had a nice epiphany.

A recent Go release (1.13) graduated Edward curves into the stdlib, meaning they are also now fully integrated into the TLS crypto. This is super news, because I could drop the old ECDSA crypto for ED25519 (smaller keys, more secure). The signatures are also deterministic, which means the the TLS cert itself no longer needs to be part of the identity, because it can be regenerated on the fly. The only place this might not work is for public identities, as I'm unsure I can poke deep enough into Go's HTTPS/TLS code to add a custom cert verification hook.

What does this all mean from a UI perspective? The pairing secret just got meaningfully smaller :)

qrold

vs.

qrnew

Still working on getting event checkin codes down to a similar size. Not sure if I can, it needs a bit of TLS/HTTPS/Go code fu.

@daodesigner
Copy link
Contributor

daodesigner commented Mar 26, 2020 via email

@karalabe
Copy link
Member Author

Phew, coronanet/go-coronanet#25. Spent all weekend + 3 entire afternoons gutting everything out and rewriting the entire P2P layer. 3500 line diff on a 3000 line codebase.

The new communication model is "eventual consistency", meaning that peers are generally disconnected from each other, and based on how important an update is, they connect and push it out faster or slower. I still need to finish the infra for this, currently the scheduler is a bit hacked in. Will do that tonight + add a debug endpoint for manually force connection to a peer to allow testing without waiting for the scheduling timeouts (hours).

@karalabe karalabe mentioned this issue Mar 31, 2020
6 tasks
@daodesigner
Copy link
Contributor

Moving conversation from #12 back here

  • I'm wondering if we could turn the first one into the splash screen that just shows up while things are loading and then switch over to the second for signup?

Hard to Mock loading screen in Figma but consider it done.

  • On the second page, I'd replace the generate private key with simply create new user. All the crypto and P2P and decentralized mumbo jumbo are irrelevant for the user actually in front of the screen.

Done.

  • For signing up, I think a subset of the profile update screen would be needed. The only really important thing to set initially is a single full-name string. Everything else can be done later (especially virus status and message and whatnot), definitely not when creating a user.

Done.

Ben hits QR/pair  --> *Display QR on screen while valid* // should agree on a timeout so people cant spam your phone?
Alissa hits QR/scan -->  *Scan QR with camera* --> Display Profile Page ---> Alissa hits Follow //Remove the contact if navigates away instead
Alissa hits profile/Ben --> Unfollow (delete contact) 

*know some of this UX is missing presently from prototype

Done.

https://www.figma.com/proto/y3VSBxXOrX6f6tCeHFF7HB/Corona-Net?node-id=1%3A4438&scaling=min-zoom

@karalabe
Copy link
Member Author

karalabe commented Apr 4, 2020

Spent a bit of time sketching out how the more advanced pairing could work. The use cases behind the below chart were:

  • Support exchanging profiles before finalizing the pairing. This should help ensure that you are indeed "friending" the correct person. Note however, that the other side can easily lie and send arbitrary profiles, so this won't stop a proper attack, but it can avoid accidental pairings.
  • Support pairing with more than one person through a single endpoint/secret. Here the point might be that you can use the QR code to add more friends at the same time, or alternatively send a single link to multiple people and have it work. This entails making the pairing long-er lived and accepting arbitrary many joins.
  • You can create a pairing session, send the link over to your friend, and have them come back whenever. It doesn't have to be immediate. Note though, you must be online when they do decide to join you, since there's only direct, live communication in corona network.

pairing

Based on the above requirements, I sketched up the workflow below:

  • Alice creates a pairing session. This is akin to creating a temporary identity and address which can be shared with random people and then just thrown away. The backend will return the identity and address.
  • From this point onward Alice will do long-polls on the API, waiting for someone to come knocking on the pairing session (a blocking HTTP GET, which needs to be repeated until the session is torn down).
  • Alice can send this temporary address to Bob via QR code scan, URL, or whatever best works. We just need to somehow get 64 bytes to Bob.
  • Bob feeds this address into his Corona Network backend, which will connect to Alice through Tor and retrieve Alice's profile. Bob does not send his profile or any other data over yet. The point is that this is Alice's show (url), they need to prove themselves first.
  • If Bob likes the profile, he clicks "Connect" on the UI, which will send their profile + pubkeys over to Alice via Tor. Bob's HTTP request is blocking until Alice reacts too.
  • Alice's GET returns at this point with Bob's profile, if Alice likes it and hits Connect too, we can accept the pairing, sending over Alice's pubkey to Bob. At this point both sides have successfully paired and shared each other identities, so Corona Network can directly connect to each other and the pairing endpoint is not needed any more.
  • Alice might keep it alive for other people or might tear it down.

Synchronicity requirements:

  • Communication is always between 2 phones directly. Even if Alice shares the link on Facebook, both Alice and Bob must be online for the pairing exchange. This might need to be conveyed somehow via a UI (either tell Bob to try later, or automatically try in the background).
  • Since Alice doesn't know when Bob will come knocking with his profile, she needs to poll the paring endpoint with a blocking HTTP GET. We could do it with websockets too, but I feel that would be a huge complication at this point, let's not go there just yet.
  • After Bob accepts Alice's profile, we still need Alice to do the same. That might take long if Alice is not on her phone right now, so Bob needs to again do long polls, waiting for Alice to confirm the join.

This pairing workflow should be able to handle a lot of very complex interactions, but it is a lot more complex than the previous one. On the backend side it's fine, it's just a few more back and forth on an already established channel + some REST endpoints, so I can do that easily. On the frontend side however things get a lot more complex, since we have multiple steps on both sides that have certain async to them. Do you think @daodesigner that this is something you'd be willing to do?

Also general feedback welcome. I haven't yet figured out the exact protocol details and the REST API details, I'm mostly trying to just sketch up the general exchange, then we can wrap it in something that makes sense and is easy.

@karalabe
Copy link
Member Author

karalabe commented Apr 5, 2020

Been thinking that we might want to leave the fancy pairing for a second release, not the initial PoC. The UX is significantly better than what we have currently, but the current one is workable and a viable starting point. There are enough other hard problems to solve in getting this off the ground.

To take a next step, I've specced out the way events could work, both from a user's perspective as well as technically + wire protocol wise. Will sleep on it to see if it still makes sense tomorrow, and if so, I'll try to define the REST API + implement the whole thing by tomorrow evening.

https://github.com/coronanet/go-coronanet/blob/master/spec/events.md

Again, the same thing holds as for pairing, I'm trying to aim for the minimal subset of features that allow events to work. I'm sure we could make them even nicer like confirming a checking after scanning the QR code.

@karalabe
Copy link
Member Author

Well, I didn't expect that basic event support will land at 3000 LOC. Either way, that's not upstreamed, so a event hosting and joining is now operational. It follows the event spec (updated since last time) and also ships the REST APIs for events.

Although many of the low level things have proper tests, I gave up on using Postman to test the API. Too many things can break, too many scenarios need testing and I'm incapable of manually doing that any more. Thus I started on an integration test suite on top of the APIs, running multiple nodes against each other. coronanet/go-coronanet#31

For now I'm polishing up the basics, found some issues in pairing + adding trace logs to everything so I can see what's going on. All in all I think the system is pretty amazingly stable, but I do need to iron out all the nasty (synthetic) corner cases.

@daodesigner
Copy link
Contributor

daodesigner commented Apr 12, 2020

Awesome, got a little side tracked but sounds like we're ready to implement a full MVP UI. Have raised funding to allow me to work on this around 20hrs/week for the next few months, will try to make everything as plug-able as possible for a UX revamp once this grows up into a full fledged social network. Let's try to agree on a final MVP for the Coronanet prototype in the next few days: https://www.figma.com/proto/y3VSBxXOrX6f6tCeHFF7HB/Corona-Net?node-id=1%3A4438&scaling=min-zoom
I can then crunch out most of the app MVP by the end of next week based on the prototype ( once I get your thumbs up ofcourse).

Well, I didn't expect that basic event support will land at 3000 LOC. Either way, that's not upstreamed, so a event hosting and joining is now operational. It follows the event spec (updated since last time) and also ships the REST APIs for events.

I'd just started to wrap my head around the last 3000L diff for the P2P layer coronanet/go-coronanet#25 😅. the test suite is awesome. Will pull the updated rest API into the ghostbridge context in the RN side and post in the coronanet repo to make sure I understand all the changes.

@daodesigner
Copy link
Contributor

@karalabe ?

@karalabe
Copy link
Member Author

Sorry for dropping the ball on this. I went way overboard with the push and managed to get into a mini-burnout. Will try to gradually ease myself into the project again.

@daodesigner
Copy link
Contributor

daodesigner commented Jun 5, 2020

Hey @karalabe just a friendly bump on this project. I really feel like this needs to exist and I'm starting to lose sleep thinking about the project just sitting here. Anyway we can pick this up again or that I could fork/branch/be added to the project/pay you for a license/open source the project to keep the vision of a privacy first/decentralized social network alive?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:ui User interface work
Projects
None yet
Development

No branches or pull requests

3 participants