Skip to content
This repository was archived by the owner on May 12, 2021. It is now read-only.

Conversation

@Powersource
Copy link
Contributor

@Powersource Powersource commented May 30, 2019

Fixes #1059

todo:

  • Remove console.logs
  • All the other things

@Powersource
Copy link
Contributor Author

@christianbundy something's up with the build here https://travis-ci.com/ssbc/patchwork/jobs/204252693

@christianbundy
Copy link
Contributor

Yeah, Travis says their Windows VM is in "early access", which in my experience means "fails randomly about 5% of the time". In the past restarting the Windows job usually does the trick, I'll do that now and we'll see if that resolves it.

@christianbundy
Copy link
Contributor

🎉

@trosel
Copy link

trosel commented Jul 18, 2019

Looking forward to this! Easy to invite friends directly. Much harder to explain to them how pubs work 😅

@Powersource
Copy link
Contributor Author

Currently trying to get this PR merged.

@Powersource
Copy link
Contributor Author

That PR is finally merged!

@christianbundy
Copy link
Contributor

@Powersource Is this PR ready for review? I noticed it still has "WIP" in the title.

@Powersource
Copy link
Contributor Author

Powersource commented Oct 14, 2019 via email

@dominictarr
Copy link
Contributor

was just checking to see if this was supported, hmm, currently patchbay is only front end client that supports peer-invites.

@arj03
Copy link
Member

arj03 commented Feb 20, 2020

Wasn't there some money from the handshake grant for patchwork work or has that been used @Powersource ? If not I think this PR would be an ideal candidate. There are still a lot of users of patchwork.

@Powersource
Copy link
Contributor Author

@arj03 No I think most of that money is still unused. I previously asked the others if I could do this and bill it but didn't get a response. I might just implement it and post an expense to the opencollective or something and see what happens :P

@arj03
Copy link
Member

arj03 commented Feb 21, 2020

Yeah I mean there appears to be around 5k$ sitting in the account. And again I think it is a really good use of the money. Also some money should be allocated to the person reviewing this.

I feel a bit like an elephant barging in here, but it just seems to me that we should use the money we have for something at least ;-)

Maybe bring this up on SSB to see what people feel?

Personally if most of the new energy is in something like oasis, then I think it would make sense to allocate some of the funds towards making it easy to switch from patchwork (for one thing an easy installer).

But again that is a whole different question. Also I think it maintenance of patchwork should be rewarded. Looking at the releases page I can see there are still regular releases.

Ping: @christianbundy

@christianbundy
Copy link
Contributor

Yep, I'd really like to use the money but feel uncomfortable just writing a check to myself. I'd be comfortable funding some of this work on supporting peer invites, I think it's silly to just leave $5k in an account somewhere but we really don't have a process for spending it.

@black-puppydog
Copy link
Contributor

I think the process is pretty much the same as it ever has been for #handshake-council, no? Write a small description on SSB, mention some folks on the council, get it approved, start work?

@christianbundy
Copy link
Contributor

I think that was the case for the money managed directly by the council, but they sent money directly to the OpenCollective accounts for Patchwork, Patchbay, Patchfox, and Manyverse (I think) to spend directly on the project however they'd like. Cinnamon and Powersource and I agreed that we'd support each other and provide accountability, approving any expense as long as 2/3 of us were okay with it, but nobody has submitted an expense yet.

I think Patchbay is using the same hourly rate as the Sunrise Choir, $40/hr, maybe we support like 6 or 12 hours on peer invites and see what happens? I'd really like to spend some of the money fixing up dependencies, which will continue to be used long after Patchwork is gone, but I'd be comfortable starting with peer invites and would be excited to have them available in Patchwork.

@arj03
Copy link
Member

arj03 commented Feb 21, 2020

I don't think you should feel bad about invoicing your own work. As I understand it from Jacob you have several people that will probably say something if it feels wierd. Especially considering you are also doing oasis.

@black-puppydog
Copy link
Contributor

Yes I agree with @arj03 here. Those funds are specifically for doing the valuable work that is patchwork maintenance.

@Powersource
Copy link
Contributor Author

Oh shit the pub seems to have somehow published the confirm message! Now to figure out what I did to make it work hehe

@Powersource
Copy link
Contributor Author

WOO IT WORKS

@Powersource
Copy link
Contributor Author

Generated a new invite and saw that arj's server had a net: connection now, net:between-two-worlds.dk:8008~shs:lbocEWqF2Fg6WMYLgmfYvqJlMfL7hiqVAV6ANjHWNw8= so I just used that one and now I'm replicating and indexing like crazy :D

@Powersource
Copy link
Contributor Author

Powersource commented Apr 18, 2020

Ok finished indexing. Some weird bugs now: I seem to have downloaded everything from the inviter (my regular @Powersource account) and the people the inviter is following (if I go to their profiles/channels I can see everything like normal), but patchwork says that I'm not following @Powersource (and that account is not following me either) and the Public feed is empty.

Also, conn.json only seems to contain arj's server, plus a few entries pointing to @cryptix's phone?! @uOReuhnb9+mPi5RnTbKMKRr3r87cK+aOg8lFXV/SBPU=.ed25519

I'm gonna try to look around a bit to see if I can fix this, but this is more uncharted territory for me so input/help is welcome.

@Powersource
Copy link
Contributor Author

Yeep if I run

      onceTrue(api.sbot.obs.connection, ssb => {
        ssb.friends.get({
          source: '@++IG2UtTTOatdHVvrbFsr7f8+MwrLN09jNheUQzkOoE=.ed25519', // my new profile
        }, (err, res) => {
          if (err) console.error('fr', err)

          console.log('friends res:', res)
        })
      })

I get

friends res: { '@Vz6v3xKpzViiTM/GAe+hKkACZSqrErQQZgv4iqQxEn8=.ed25519': true } // my regular profile

so it probably has something to do with patchwork's custom friend graph code, the index patchwork-contacts or the like.

@Powersource
Copy link
Contributor Author

I tried

diff --git a/lib/plugins/contacts.js b/lib/plugins/contacts.js
index 147c061b..d0fe78eb 100644
--- a/lib/plugins/contacts.js
+++ b/lib/plugins/contacts.js
@@ -54,15 +54,10 @@ exports.init = function (ssb) {
     raw: view,
 
     isFollowing: function ({ source, dest }, cb) {
-      if (values && values[source]) {
-        cb(null, values[source][dest] === true)
-      } else {
-        view.get((err, graph) => {
-          if (err) return cb(err)
-          const following = graph && graph[source] && graph[source][dest] === true
-          cb(null, following)
-        })
-      }
+      ssb.friends.get({ source, dest }, (err, res) => {
+        if (err) return cb(err)
+        cb(null, res === true)
+      })
     },
 
     isBlocking: function ({ source, dest }, cb) {

and now I can see my regular profile in the Public feed (just like I'm following it), but patchwork still says the profiles aren't following each other, this implementation is really weird hehe.

I would like to use that same logic (friends.get) a bit earlier in the process, I have a feeling that might work. Here, to be specific https://github.com/ssbc/patchwork/blob/master/lib/plugins/contacts.js#L39 But FlumeReduce only seems to let that map function be sync and friends.get is async. Anyone got a good idea for a workaround? I'd rather not reim


ok so I might have tried to reimplement it. however, it doesn't work :( The index seems to look exactly like it usually does. now I'm going to bed. probably going to need help with this before I can continue

diff --git a/lib/plugins/contacts.js b/lib/plugins/contacts.js
index 147c061b..1c252bc3 100644
--- a/lib/plugins/contacts.js
+++ b/lib/plugins/contacts.js
@@ -18,11 +18,32 @@ exports.init = function (ssb) {
   const view = ssb._flumeUse('patchwork-contacts', FlumeReduce(0, function reduce (result, item) {
     // used by the reducer view
     if (!result) result = {}
+
+    if (item.invites && item.accepts) {
+      // code doesn't get here, why?!
+      // once we get here, we might have to also save item.invites and item.accepts into result
+
+      for (const guest in item.accepts) {
+        const inviter = item.invites[item.accepts[guest]]
+
+        if (inviter) {
+          if (!result[inviter]) result[inviter] = {}
+          if (!result[guest]) result[guest] = {}
+
+          // only consume invites once. probably better to also check confirm messages but we should just switch to using ssb-friends properly for that
+          if (!result[inviter][guest]) result[inviter][guest] = true
+          if (!result[guest][inviter]) result[guest][inviter] = true
+        }
+      }
+    }
+
     if (item) {
       for (const author in item) {
-        for (const contact in item[author]) {
-          if (!result[author]) result[author] = {}
-          result[author][contact] = item[author][contact]
+        if (author !== 'invites' && author !== 'accepts') {
+          for (const contact in item[author]) {
+            if (!result[author]) result[author] = {}
+            result[author][contact] = item[author][contact]
+          }
         }
       }
     }
@@ -33,10 +54,26 @@ exports.init = function (ssb) {
     return result
   }, function map (msg) {
     // used by the reducer view
-    if (msg.value && msg.value.content && msg.value.content.type === 'contact' && ref.isFeed(msg.value.content.contact)) {
-      return {
-        [msg.value.author]: {
-          [msg.value.content.contact]: getContactState(msg.value.content)
+    if (msg.value && msg.value.content) {
+      const type = msg.value.content.type
+
+      if (type === 'contact' && ref.isFeed(msg.value.content.contact)) {
+        return {
+          [msg.value.author]: {
+            [msg.value.content.contact]: getContactState(msg.value.content)
+          }
+        }
+      } else if (type === 'peer-invite') {
+        return {
+          invites: {
+            [msg.value.key]: msg.value.author
+          }
+        }
+      } else if (type === 'peer-invite/accept') {
+        return {
+          accepts: {
+            [msg.value.author]: msg.value.content.receipt
+          }
         }
       }
     }

@arj03
Copy link
Member

arj03 commented Apr 19, 2020

Hey @Powersource, that is great news!

The invite functionality in browser is hacked a bit because I didn't want to port over all the stuff. So that's probably why it works in the browser but the invite is invalid in other clients. Can you send me one generated from both?

Great to hear that it helped with the device-address I added to my pub. Would probably be good with a list of what is needed from pub admins so we can get others to upgrade.

@christianbundy might be more familiar with how the contacts is working in patchwork. I havn't looked.

@black-puppydog
Copy link
Contributor

I'm a bit confused here... peer invites and DHT invites are the same, right?
So this PR would add the capability to create these invites, while #1246 would only allow them to be accepted. Is that correct?

@Powersource
Copy link
Contributor Author

No they're pretty different. Their repos are https://gitlab.com/staltz/ssb-dht-invite and https://github.com/ssbc/ssb-peer-invites if you want to read more.

@Powersource
Copy link
Contributor Author

Gonna highlight this a bit more

probably going to need help with this before I can continue

I'd love to pair program a bit on this with someone who feels comfortable-ish with developing for flume and/or patchwork.

@black-puppydog
Copy link
Contributor

Thank you @Powersource for clarifying that. I don't know how I missed this. I guess I conflated the two from the very beginning. Very much not qualified to pair up on this though, sorry :(

@christianbundy
Copy link
Contributor

Can we find some time to pair on this? My brain works between like 09:00 and 15:00 Pacific time. Maybe helpful. I'm pretty comfortable with FlumeDB but I don't think anyone understands Patchwork.

@elavoie
Copy link

elavoie commented Apr 25, 2020

I think that was the case for the money managed directly by the council, but they sent money directly to the OpenCollective accounts for Patchwork, Patchbay, Patchfox, and Manyverse (I think) to spend directly on the project however they'd like. Cinnamon and Powersource and I agreed that we'd support each other and provide accountability, approving any expense as long as 2/3 of us were okay with it, but nobody has submitted an expense yet.

I think Patchbay is using the same hourly rate as the Sunrise Choir, $40/hr, maybe we support like 6 or 12 hours on peer invites and see what happens? I'd really like to spend some of the money fixing up dependencies, which will continue to be used long after Patchwork is gone, but I'd be comfortable starting with peer invites and would be excited to have them available in Patchwork.

I will let you guys figure the technical stuff.

Regarding the governance of Patchwork funding, you guys have all a go from me to spend it. I took the initiative of asking for a Patchwork Open Collective, hoping this could allow the Handshake Council to focus on other things, but it seems this required a little more help on the governance side of things.

You can also write checks to yourselves, all of you are long-time community members with plenty of trust. 40$/h seems fine to me and we can combine that with some funds from the SSBC. If you guys aim for 10h/month of funded work (400$/month) coming 50/50 from SSBC (200$/month) and Patchwork (200$/month), we can support that for at least a year. We can also discuss with Mix to cover more funding from Scuttlebutt Maintenance if 10h/month is not enough to clear up the backlog.

@elavoie
Copy link

elavoie commented Apr 25, 2020

Just to clarify the intention of why getting the SSBC involved: I am trying to establish sustainable flows of money. Currently our only sustainable source is the 200$/month that comes in recurrent donation in the SSBC. We need to spend these regularly enough to show backers that their money is necessary and useful. This way this will incentivize more backers to support SSB in general, and their preferred clients in particular.

Still being the most used client, Patchwork maintenance seems like a prime candidate for leveraging recurrent funds and bootstrapping a maintenance team. My current thinking along these lines is to fund those that review and merge PRs (and therefore take responsibility of the quality of the code base), and encourage more volunteers to fix the easy and low-hanging fruits. I can create a separate issue to discuss governance, maintenance, and funding if you guys want to discuss this in more detail.

@Powersource
Copy link
Contributor Author

@christianbundy Thanks! Will write to you on signal

@elavoie I like all of these words that you're writing, yeah let's keep discussing this in a new issue :)

@Powersource
Copy link
Contributor Author

Had a call with Christian and we got a bit further

diff --git a/lib/plugins/contacts.js b/lib/plugins/contacts.js
index 147c061b..796cfb4a 100644
--- a/lib/plugins/contacts.js
+++ b/lib/plugins/contacts.js
@@ -18,11 +18,44 @@ exports.init = function (ssb) {
   const view = ssb._flumeUse('patchwork-contacts', FlumeReduce(0, function reduce (result, item) {
     // used by the reducer view
     if (!result) result = {}
+
+    for (const inviteMsgKey in item.invites) {
+      if (!result.invites) result.invites = {}
+      if (!result.invites[inviteMsgKey]) result.invites[inviteMsgKey] = item.invites[inviteMsgKey]
+    }
+
+    for (const invited in item.accepts) {
+      if (!result.accepts) result.accepts = {}
+      if (!result.accepts[invited]) result.accepts[invited] = item.accepts[invited]
+    }
+
+    if (result.invites && result.accepts) {
+      for (const guest in result.accepts) {
+        const inviteMsgKey = result.accepts[guest]
+        const inviter = result.invites[inviteMsgKey]
+
+        if (inviter) {
+          if (!result[inviter]) result[inviter] = {}
+          if (!result[guest]) result[guest] = {}
+
+          if (!result[inviter][guest]) result[inviter][guest] = true
+          if (!result[guest][inviter]) result[guest][inviter] = true
+
+          // todo: uncomment this so invites can only be consumed once
+          // should maybe also check for confirm message from a pub
+          // delete result.invites[inviteMsgKey][inviter]
+          // delete result.accepts[guest][inviteMsgKey]
+        }
+      }
+    }
+
     if (item) {
       for (const author in item) {
-        for (const contact in item[author]) {
-          if (!result[author]) result[author] = {}
-          result[author][contact] = item[author][contact]
+        if (author !== 'invites' && author !== 'accepts') {
+          for (const contact in item[author]) {
+            if (!result[author]) result[author] = {}
+            result[author][contact] = item[author][contact]
+          }
         }
       }
     }
@@ -33,10 +66,26 @@ exports.init = function (ssb) {
     return result
   }, function map (msg) {
     // used by the reducer view
-    if (msg.value && msg.value.content && msg.value.content.type === 'contact' && ref.isFeed(msg.value.content.contact)) {
-      return {
-        [msg.value.author]: {
-          [msg.value.content.contact]: getContactState(msg.value.content)
+    if (msg.value && msg.value.content) {
+      const type = msg.value.content.type
+
+      if (type === 'contact' && ref.isFeed(msg.value.content.contact)) {
+        return {
+          [msg.value.author]: {
+            [msg.value.content.contact]: getContactState(msg.value.content)
+          }
+        }
+      } else if (type === 'peer-invite') {
+        return {
+          invites: {
+            [msg.key]: msg.value.author
+          }
+        }
+      } else if (type === 'peer-invite/accept') {
+        return {
+          accepts: {
+            [msg.value.author]: msg.value.content.receipt
+          }
         }
       }
     }

but now I'm in the same state that I described before when I tried friends.get

and now I can see my regular profile in the Public feed (just like I'm following it), but patchwork still says the profiles aren't following each other,

and I don't know if it did this before (I don't think so) but now I'm gossiping with more than the pub that invited me.

I think now the other files lib/depject/profile/obs/contact.js and/or lib/depject/contact/obs.js might be playing into it? Or there's just more to do in that same file?

Leaning towards dropping this project now, we'll see, even if I think this still is very important.

@Powersource
Copy link
Contributor Author

So I'm un-committing from this work now (i.e. could technically work more on this, but no promises from now on).

Ways forward for anyone picking this up:

  • Finish the diffs I've posted here (i.e. continue modifying patchwork's custom contact/friend logic). Probably the "simplest" solution in that it would take the least amount of lines of code written, but you'd need to be a bit lucky to figure out exactly which those lines would be.
  • Get rid of the custom patchwork contact/friend logic and just use plain ssb-friends. I think we'd need to do How can we tell the difference between public and private follows/blocks? ssb-friends#43 (can probably find that logic in manyverse). Plus all the work of replacing patchwork-contacts which would probably be a bunch of work and should be done in another PR. This solution is probably the cleanest, but would take a bunch of work, and there's no guarantee you won't run into other exotic patchwork bugs in the process (in fact this is likely to happen).
  • Make the invited person publish a follow message on invite accept, and the inviter publish a follow message when they see who has accepted the invite. This solution might be the "easiest" solution since we would know sort of what to do and would hopefully not be too much work, but would be very hacky, probably buggy, suboptimal, and would still include diving into weird patchwork code.

Doing some math based on this comment:

I've clocked 11 hours (that's pretty heavily rounded down from the actual hours but I'm fine with not counting the extra ones)

11 * $40 = $440 USD

Submitted an invoice here https://opencollective.com/patchwork/expenses/17418

@stale
Copy link

stale bot commented Aug 1, 2020

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add ability to create & use peer-invites

8 participants