// test/result-write-once.js — the canonical result is WRITE-ONCE.
//
// Two peers share a pool. The owner writes the canonical result for a content
// key; a second peer then appends a CONFLICTING result for the SAME
// (codeHash, inputHash). The fold must keep the first (canonical) result on
// BOTH peers — the conflict is ignored, not applied last-write-wins. This is
// the P0 floor that makes a memoized chunk trustworthy (SPEC §4.1).
const test = require('brittle')
const Corestore = require('corestore')
const tmp = require('test-tmp')
const { replicateAndSync } = require('autobase-test-helpers')
const { ComputeNode } = require('../lib/node')
const codeHash = 'square-v1'
const inputHash = 'deadbeefcafe'
test('result is write-once: a later conflicting result cannot clobber the canonical chunk', async (t) => {
const owner = await ComputeNode.create(new Corestore(await tmp(t)), null, {})
await owner.grantSelf('owner')
const worker = await ComputeNode.create(new Corestore(await tmp(t)), owner.key, {})
await owner.addWriter(worker.writerKey)
await replicateAndSync([owner.base, worker.base])
t.ok(worker.base.writable, 'worker became a writer')
// owner writes the canonical result first, and it fully linearizes before
// any conflict exists (so causal order pins it first in the fold).
await owner.base.append({ type: 'result', codeHash, inputHash, output: 49, worker: owner.idHex })
await replicateAndSync([owner.base, worker.base])
t.is(await owner.lookup(codeHash, inputHash), 49, 'canonical result present after first write')
// worker appends a CONFLICTING result for the same content key
await worker.base.append({ type: 'result', codeHash, inputHash, output: 999, worker: worker.idHex })
await replicateAndSync([owner.base, worker.base])
// write-once: the first result wins on BOTH peers; the conflict is dropped
t.is(await owner.lookup(codeHash, inputHash), 49, 'owner: canonical result NOT clobbered')
t.is(await worker.lookup(codeHash, inputHash), 49, 'worker: canonical result NOT clobbered')
await owner.close()
await worker.close()
})