automerge-classic icon indicating copy to clipboard operation
automerge-classic copied to clipboard

Unidirectional sync?

Open skokenes opened this issue 3 years ago • 3 comments

Can the new syncing protocol be used to sync in one direction only? Ie, assume we have a read-only peer that we don't want to accept changes from.

My use case involves a centralized server (hub) that peers communicate through. Some peers are meant to be in "read-only" mode; they should sync with data from other peers but aren't ever supposed to introduce their own changes.

Beyond the obvious "don't make changes to a peer you want to be read-only", is there a way to use the sync protocol in a way that ensures that even if a bad actor somehow makes a change to a peer that is supposed to be read-only, those changes will be rejected when syncing with other peers?

skokenes avatar May 17 '21 19:05 skokenes

Interesting case. Can I restate it to see if I understood it correctly? Peer A is syncing with peer B, and you want to ensure that changes can only flow from A to B, but not vice versa. If B has made changes, A should reject them.

I haven't tried it, but I think the following might work. When A receives a message from B:

// Returns true if the message should be passed to receiveSyncMessage,
// or false if the message should be dropped and the connection closed.
function shouldProcessMessage(doc, message) {
  const parsedMsg = Automerge.Backend.decodeSyncMessage(message)
  const backend = Automerge.Frontend.getBackendState(doc)
  const headsKnown = parsedMsg.heads.every(head => Automerge.Backend.getChangeByHash(backend, head))
  return (parsedMsg.length === 0 && headsKnown)
}

ept avatar May 17 '21 19:05 ept

Interesting, I will give that a go. The only part I don't understand is why you check parsedMsg.length === 0 at the end?

skokenes avatar May 17 '21 19:05 skokenes

Oops, sorry, that should have been parsedMsg.changes.length === 0.

ept avatar May 17 '21 20:05 ept