refuse re-adding a dataful ghost msg

This commit is contained in:
Andre Staltz 2023-10-25 19:09:19 +03:00
parent 8c3800264a
commit 4fff37ad02
No known key found for this signature in database
GPG Key ID: 9EDE23EA7E8A4890
2 changed files with 65 additions and 8 deletions

View File

@ -151,6 +151,35 @@ class Ghosts {
})
}
/**
* @param {string} tangleID
* @param {string} msgID
* @param {CB<void>} cb
*/
remove(tangleID, msgID, cb) {
this.#loaded.onReady(() => {
if (!this.#maps.has(tangleID)) return cb()
const map = /** @type {Map<string, number>} */ (this.#maps.get(tangleID))
if (!map.has(msgID)) return cb()
const newMap = new Map(map)
newMap.delete(msgID)
atomic.writeFile(
this.#path(tangleID),
this.#serialize(newMap),
Ghosts.encodingOpts,
(/** @type {any} */ err) => {
// prettier-ignore
if (err) return cb(new Error('GhostDB.save() failed to write ghost file', { cause: err }))
this.#maps.set(tangleID, newMap)
cb()
}
)
})
}
/**
* @param {string} tangleID
* @returns {Map<string, number>}

View File

@ -355,21 +355,25 @@ function initDB(peer, config) {
try {
accountTangle = getAccountTangle(rec)
} catch (err) {
// prettier-ignore
return new Error('Failed to identify the account of this msg', { cause: err })
return new Error('Unknown account tangle owning this msg', { cause: err })
}
const pubkeys = getPubkeysInAccount(accountTangle)
// Don't accept ghosts to come back, unless they are trail msgs
if (!!rec.msg.data && ghosts.read(tangleID).has(rec.id)) {
return new Error('Refusing a ghost msg to come back')
}
let err
if ((err = MsgV3.validate(rec.msg, tangle, pubkeys, rec.id, tangleID))) {
return new Error('Failed msg validation', { cause: err })
return new Error('Invalid msg', { cause: err })
}
// Account tangle related validations
if (rec.msg.metadata.account === ACCOUNT_SELF) {
const validAccountTangle = /** @type {Tangle} */ (accountTangle)
if ((err = validateAccountMsg(rec.msg, validAccountTangle))) {
return new Error('Failed msg account validation', { cause: err })
return new Error('Invalid account msg', { cause: err })
}
}
@ -410,11 +414,17 @@ function initDB(peer, config) {
return cb(new Error('add() failed to verify msg', { cause: err }))
}
// The majority of cases don't have ghosts to be removed, but this operation
// is silent and cheap if there are no ghosts.
removeGhost(tangleID, msgID, (err) => {
// prettier-ignore
if (err) return cb(new Error('add() failed to remove ghost', { cause: err }))
logAppend(msgID, msg, (err, rec) => {
if (err) return cb(new Error('add() failed in the log', { cause: err }))
onRecordAdded.set(rec)
cb(null, rec)
})
})
}
/**
@ -962,6 +972,24 @@ function initDB(peer, config) {
})
}
/**
* @param {MsgID} tangleID
* @param {MsgID} msgID
* @param {CB<void>} cb
*/
function removeGhost(tangleID, msgID, cb) {
// prettier-ignore
if (typeof tangleID !== 'string') return cb(new Error('ghosts.remove() requires tangleID in the 1st arg'))
// prettier-ignore
if (typeof msgID !== 'string') return cb(new Error('ghosts.remove() requires msgID in the 2nd arg'))
ghosts.remove(tangleID, msgID, (err) => {
// prettier-ignore
if (err) cb(new Error('ghosts.remove() failed to save to disk', { cause: err }))
else cb()
})
}
/**
* @param {MsgID} tangleID
* @returns {Array<string>}