amark / gun

An open source cybersecurity protocol for syncing decentralized graph data.
https://gun.eco/docs
Other
17.93k stars 1.16k forks source link

If you put data in a key with one gun instance, then change that data on another gun instance, the first instance will be unable to read the change #1330

Open ViteOrder opened 1 year ago

ViteOrder commented 1 year ago

Minimal reproduable example, would print true twice if there werent a bug.

Heres a senario where having multiple instances is handy: You want to give someone else permission to write certificates for a node, so you make that node its own SEApair, and give you and that other person a copy of the pair. Now you and your friend write data into it by making a new gun instance, and authing into it.

amark commented 1 year ago

Peering the 2 instances will work (erm... there's an example of how to do this buried somewhere)

But it may be pretty hard to do this without because it means the adapter has to be aware of changes/modifications to the filesystem, and it would need to know how to do this uniformly across all file systems (browser, cloud, desktop, etc.) which would complicate things pretty quickly.

Without peering, GUN has no way of knowing whether the 2 instances aren't actually separate machines, threads, processes, etc. do you have any clever ideas?

draeder commented 1 year ago

If I'm not misunderstanding the issue and example, I believe that the desired use-case is what I did with Gunsafe CLI's sync functionality.

ViteOrder commented 1 year ago

I dont know about any of this peering buiness. For my usecase, if I were just able to be authed into multiple users on one instance, I'd be golden

Maybe if the put function had an option like this: .put(data, undefined, {opt: {putAsUser: SEApair}}) now that would be perfect

draeder commented 1 year ago

I think what you're looking for is GUN's Certify

dirtboll commented 1 year ago

I've stumbled across this issue too when I tried to write unit tests for different gun instances with different users. After reading the localStorage.js I thought it was impossible to sync between two local peers only through the storage layer since gun only read the db once at "create" event (cmiiw). Soon it's confirmed by Mark that it needs peering. I also considered to use SEA.certify() but it gives me privacy issue for my use case since gun sends the certificate along with the associated public key for every put using it. Though I'm interested to know how to put for multiple user without login or certify.

For now, I just use peering as a workaround. I didn't aware that there's documented example to do this so I implemented my own. :/

Here's what I've come up with.

function makePeerFrom(gun) {
  let { mesh, pid } = gun.back("opt"), peer = {
     id: pid,
     wire: {
       send(msg) { if (msg) mesh.hear(msg, peer); }
     }
  }
  return peer
}

function doPeering(gun1, gun2) {
   let [peer1, peer2] = [makePeerFrom(gun1), makePeerFrom(gun2)]
   let [{mesh: mesh1}, {mesh: mesh2}] = [gun1.back("opt"), gun2.back("opt")]
   mesh1.hi(peer2)
   mesh2.hi(peer1)
}

I've updated the code from your example with my method, it now prints true twice.