diff --git a/src/clock/index.js b/src/clock/index.js index 30a41774..1bd161d6 100644 --- a/src/clock/index.js +++ b/src/clock/index.js @@ -94,12 +94,30 @@ export class EventFetcher { * @returns {Promise>} */ export const encodeEventBlock = async (value) => { - // TODO: sort parents - const { cid, bytes } = await encode({ value, codec: cbor, hasher: sha256 }) + if (typeof value.data === 'undefined' || !Array.isArray(value.parents)) { + throw new Error('invalid event block structure') + } + const { data } = value + const parents = [...value.parents].sort((a, b) => compareBytes(a.bytes, b.bytes)) + const { cid, bytes } = await encode({ value: { data, parents }, codec: cbor, hasher: sha256 }) // @ts-expect-error return new Block({ cid, value, bytes }) } +/** + * @param {Uint8Array} a + * @param {Uint8Array} b + */ +const compareBytes = (a, b) => { + for (let i = 0; i < a.byteLength; i++) { + if (a[i] < b[i]) return -1 + if (a[i] > b[i]) return 1 + } + if (a.byteLength > b.byteLength) return 1 + if (a.byteLength < b.byteLength) return -1 + return 0 +} + /** * @template T * @param {Uint8Array} bytes diff --git a/test/clock.test.js b/test/clock.test.js index b819e04d..3982314d 100644 --- a/test/clock.test.js +++ b/test/clock.test.js @@ -295,4 +295,12 @@ describe('clock', () => { assert.equal(head[0].toString(), event3.cid.toString()) assert.equal(count - before, 8, 'The number of traversals should be 8 with optimization') }) + + it('sorts event links', async () => { + const parent0 = await EventBlock.create(await randomEventData()) + const parent1 = await EventBlock.create(await randomEventData()) + const child0 = await EventBlock.create({}, [parent0.cid, parent1.cid]) + const child1 = await EventBlock.create({}, [parent1.cid, parent0.cid]) + assert.deepEqual(child0.bytes, child1.bytes) + }) })