mafintosh / hyperdb

Distributed scalable database
MIT License
752 stars 75 forks source link

"First shared hypercore must be the same" when trying to replicate via webrtc. #93

Open peacememories opened 6 years ago

peacememories commented 6 years ago

I'm trying to replicate a db over webrtc-swarm and always running into the dreaded "First shared hypercore must be the same" message.

Below is the code I am trying to use. I use the same key for both dbs, and as far as i can tell i am looping both replication streams similarly to the tcp example in #19 .

Does anyone notice anything I'm doing wrong?

const wrtc = require('wrtc')
const swarm = require('webrtc-swarm')

const signalhub = require('signalhub')
const hyperdb = require('hyperdb')

const db1 = init_db('./db1', { valueEncoding: 'utf-8' })

db1.on('ready', () => {
    const db2 = init_db('./db2', db1.key, { valueEncoding: 'utf-8' })
    db2.on('ready', () => {
        db1.put('/hello', 'world', () => {
            init_swarm(db1, (hub) => {
                return swarm(hub, {
                    wrtc: wrtc
                })
            })
            init_swarm(db2, (hub) => {
                return swarm(hub, {
                    wrtc: wrtc
                })
            })
        })

    })
})

function init_swarm(db, swarmfn) {
    const hub = signalhub('freemate', ['https://signalhub.mafintosh.com'])

    const sw = swarmfn(hub)

    sw.on('peer', (peer, id) => {
        console.log('found peer')
        const repstream = db.replicate()
        peer.on('data', (data) => {
            console.log('id: ', id, ' got data: ', data)
        })
        repstream.pipe(peer).pipe(repstream)
        peer.once('finish', (err) => console.log(err))
        peer.once('error', (err) => console.log(err))
    })

    return sw
}

function init_db(location) {
    const db = hyperdb(location, { valueEncoding: 'utf-8' })
    return db
}
peacememories commented 6 years ago

Nevermind, I found the main problem I think. One abstraction later too much (the key I supply is never passed through).

Another question though. Do I really need to share the key across the databases? Or can I just use authorization?

mafintosh commented 6 years ago

@peacememories what do you mean by sharing the key?

peacememories commented 6 years ago

Seems like just another misunderstanding. I assumed that providing the "key" of the first db to the second one on creation would result in both using the same key pair, but it seems the local stream key is generated every time anyway. The only question I have now is, why do I need one database to be the "first" (and supply its public key to subsequent db instances on creation)? What does that do in the background?

mafintosh commented 6 years ago

@peacememories it's part of the capability system and to have a joint discovery key. the first one to create the db, becomes the source. this simply means that the discoveryKey of the first one is the discovery key for the db forever. the first writer can disappear though without any issues.

micahscopes commented 6 years ago

@peacememories once you figure this out, I'd love to see your example!