fix thread sync when one peer has nothing

This commit is contained in:
Andre Staltz 2023-04-21 11:53:34 +03:00
parent a9fd222f0d
commit af33dc691f
2 changed files with 33 additions and 28 deletions

View File

@ -135,6 +135,7 @@ class Algorithm {
const [minDepth, maxDepth] = range const [minDepth, maxDepth] = range
const rootMsg = this.#peer.db.get(rootMsgHash) const rootMsg = this.#peer.db.get(rootMsgHash)
if (!rootMsg) return if (!rootMsg) return
if (minDepth === 0) yield rootMsg
for (const msg of this.#peer.db.msgs()) { for (const msg of this.#peer.db.msgs()) {
const tangles = msg.metadata.tangles const tangles = msg.metadata.tangles
if ( if (
@ -169,8 +170,10 @@ class Algorithm {
const validNewMsgs = newMsgs const validNewMsgs = newMsgs
.filter((msg) => { .filter((msg) => {
if (!msg.content) return true // contentless messages are always valid if (!msg.content) return true // contentless messages are always valid
const depth = msg.metadata.tangles[rootMsgHash]?.depth const depth = msg.metadata.tangles[rootMsgHash]?.depth ?? 0
if (!depth) return false // if it's not the root, it must have a depth if (depth === 0 && FeedV1.getMsgHash(msg) !== rootMsgHash) {
return false // the rootMsg is the only acceptable depth-zero msg
}
return minWant <= depth && depth <= maxWant return minWant <= depth && depth <= maxWant
}) })
.sort((a, b) => { .sort((a, b) => {

View File

@ -14,6 +14,10 @@ const createSSB = SecretStack({ appKey: caps.shs })
.use(require('ssb-box')) .use(require('ssb-box'))
.use(require('../')) .use(require('../'))
function getTexts(iter) {
return [...iter].filter((msg) => msg.content).map((msg) => msg.content.text)
}
/* /*
BEFORE dagsync: BEFORE dagsync:
```mermaid ```mermaid
@ -134,10 +138,6 @@ test('sync a thread where both peers have portions', async (t) => {
keys: daveKeys, keys: daveKeys,
}) })
function getTexts(iter) {
return [...iter].filter((msg) => msg.content).map((msg) => msg.content.text)
}
t.deepEquals( t.deepEquals(
getTexts(alice.db.msgs()), getTexts(alice.db.msgs()),
['A', 'B1', 'B2', 'C1'], ['A', 'B1', 'B2', 'C1'],
@ -177,21 +177,22 @@ test('sync a thread where both peers have portions', async (t) => {
await p(bob.close)(true) await p(bob.close)(true)
}) })
// FIXME: test('sync a thread where one peer does not have the root', async (t) => {
test.skip('sync a thread where first peer does not have the root', async (t) => {
const ALICE_DIR = path.join(os.tmpdir(), 'dagsync-alice') const ALICE_DIR = path.join(os.tmpdir(), 'dagsync-alice')
const BOB_DIR = path.join(os.tmpdir(), 'dagsync-bob') const BOB_DIR = path.join(os.tmpdir(), 'dagsync-bob')
rimraf.sync(ALICE_DIR) rimraf.sync(ALICE_DIR)
rimraf.sync(BOB_DIR) rimraf.sync(BOB_DIR)
const aliceKeys = generateKeypair('alice')
const alice = createSSB({ const alice = createSSB({
keys: ssbKeys.generate('ed25519', 'alice'), keys: aliceKeys,
path: ALICE_DIR, path: ALICE_DIR,
}) })
const bobKeys = generateKeypair('bob')
const bob = createSSB({ const bob = createSSB({
keys: ssbKeys.generate('ed25519', 'bob'), keys: bobKeys,
path: BOB_DIR, path: BOB_DIR,
}) })
@ -199,48 +200,49 @@ test.skip('sync a thread where first peer does not have the root', async (t) =>
await bob.db.loaded() await bob.db.loaded()
const rootA = await p(alice.db.create)({ const rootA = await p(alice.db.create)({
feedFormat: 'classic', type: 'post',
content: { type: 'post', text: 'A' }, content: { text: 'A' },
keys: alice.config.keys, keys: aliceKeys,
}) })
await p(setTimeout)(10) await p(setTimeout)(10)
const replyA1 = await p(alice.db.create)({ const replyA1 = await p(alice.db.create)({
feedFormat: 'classic', type: 'post',
content: { type: 'post', text: 'A1', root: rootA.key, branch: rootA.key }, content: { text: 'A1' },
keys: alice.config.keys, tangles: [rootA.hash],
keys: aliceKeys,
}) })
await p(setTimeout)(10) await p(setTimeout)(10)
const replyA2 = await p(alice.db.create)({ const replyA2 = await p(alice.db.create)({
feedFormat: 'classic', type: 'post',
content: { type: 'post', text: 'A2', root: rootA.key, branch: replyA1.key }, content: { text: 'A2' },
keys: alice.config.keys, tangles: [rootA.hash],
keys: aliceKeys,
}) })
t.deepEquals( t.deepEquals(
alice.db.filterAsArray((msg) => true).map((msg) => msg.value.content.text), getTexts(alice.db.msgs()),
['A', 'A1', 'A2'], ['A', 'A1', 'A2'],
'alice has the full thread' 'alice has the full thread'
) )
t.deepEquals( t.deepEquals(getTexts(bob.db.msgs()), [], 'bob has nothing')
bob.db.filterAsArray((msg) => true).map((msg) => msg.value.content.text),
[], bob.tangleSync.setGoal(rootA.hash, 'all')
'bob has nothing' alice.tangleSync.setGoal(rootA.hash, 'all')
)
const remoteAlice = await p(bob.connect)(alice.getAddress()) const remoteAlice = await p(bob.connect)(alice.getAddress())
t.pass('bob connected to alice') t.pass('bob connected to alice')
bob.threadSync.request(rootA.key) bob.tangleSync.initiate()
await p(setTimeout)(1000) await p(setTimeout)(1000)
t.pass('threadSync!') t.pass('tangleSync!')
t.deepEquals( t.deepEquals(
bob.db.filterAsArray((msg) => true).map((msg) => msg.value.content.text), getTexts(bob.db.msgs()),
['A', 'A1', 'A2'], ['A', 'A1', 'A2'],
'bob has the full thread' 'bob has the full thread'
) )