From f7ecc1e3734435675b92018df23ab610ee3cee1c Mon Sep 17 00:00:00 2001 From: dholms Date: Tue, 11 Feb 2025 16:41:11 -0600 Subject: [PATCH] fix bug on right sibling proof & add some tests --- packages/repo/src/mst/mst.ts | 5 +- packages/repo/tests/_keys.ts | 156 ++++++++++++++++++++ packages/repo/tests/covering-proofs.test.ts | 84 +++++++++++ 3 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 packages/repo/tests/_keys.ts create mode 100644 packages/repo/tests/covering-proofs.test.ts diff --git a/packages/repo/src/mst/mst.ts b/packages/repo/src/mst/mst.ts index fc4a6117d8d..dab7d1f34eb 100644 --- a/packages/repo/src/mst/mst.ts +++ b/packages/repo/src/mst/mst.ts @@ -775,7 +775,10 @@ export class MST { async proofForRightSib(key: string): Promise { const index = await this.findGtOrEqualLeafIndex(key) - const found = await this.atIndex(index) + let found = await this.atIndex(index) + if (!found) { + found = await this.atIndex(index - 1) + } let blocks: BlockMap if (!found) { // shouldn't ever hit, null case diff --git a/packages/repo/tests/_keys.ts b/packages/repo/tests/_keys.ts new file mode 100644 index 00000000000..2789c74cad4 --- /dev/null +++ b/packages/repo/tests/_keys.ts @@ -0,0 +1,156 @@ +export const A0 = 'A0/501344' +export const A1 = 'A1/700567' +export const A2 = 'A2/239654' +export const A3 = 'A3/570745' +export const A4 = 'A4/231700' +export const A5 = 'A5/343219' +export const B0 = 'B0/436099' +export const B1 = 'B1/293486' +export const B2 = 'B2/303249' +export const B3 = 'B3/690557' +export const B4 = 'B4/522003' +export const B5 = 'B5/528640' +export const C0 = 'C0/535043' +export const C1 = 'C1/970596' +export const C2 = 'C2/953910' +export const C3 = 'C3/016643' +export const C4 = 'C4/687126' +export const C5 = 'C5/136391' +export const D0 = 'D0/360671' +export const D1 = 'D1/637976' +export const D2 = 'D2/915466' +export const D3 = 'D3/722333' +export const D4 = 'D4/816246' +export const D5 = 'D5/611412' +export const E0 = 'E0/922708' +export const E1 = 'E1/710014' +export const E2 = 'E2/413113' +export const E3 = 'E3/226890' +export const E4 = 'E4/349347' +export const E5 = 'E5/574759' +export const F0 = 'F0/606463' +export const F1 = 'F1/415452' +export const F2 = 'F2/410478' +export const F3 = 'F3/000172' +export const F4 = 'F4/438093' +export const F5 = 'F5/131765' +export const G0 = 'G0/714257' +export const G1 = 'G1/254594' +export const G2 = 'G2/536869' +export const G3 = 'G3/188348' +export const G4 = 'G4/627086' +export const G5 = 'G5/436727' +export const H0 = 'H0/740256' +export const H1 = 'H1/113887' +export const H2 = 'H2/783135' +export const H3 = 'H3/911996' +export const H4 = 'H4/413212' +export const H5 = 'H5/205035' +export const I0 = 'I0/123247' +export const I1 = 'I1/186251' +export const I2 = 'I2/455864' +export const I3 = 'I3/874267' +export const I4 = 'I4/700662' +export const I5 = 'I5/355687' +export const J0 = 'J0/651505' +export const J1 = 'J1/747356' +export const J2 = 'J2/880562' +export const J3 = 'J3/337247' +export const J4 = 'J4/333302' +export const J5 = 'J5/802321' +export const K0 = 'K0/513509' +export const K1 = 'K1/512199' +export const K2 = 'K2/998695' +export const K3 = 'K3/030175' +export const K4 = 'K4/843537' +export const K5 = 'K5/621841' +export const L0 = 'L0/110539' +export const L1 = 'L1/902119' +export const L2 = 'L2/433601' +export const L3 = 'L3/578589' +export const L4 = 'L4/179159' +export const L5 = 'L5/411430' +export const M0 = 'M0/233209' +export const M1 = 'M1/807305' +export const M2 = 'M2/593452' +export const M3 = 'M3/412948' +export const M4 = 'M4/230935' +export const M5 = 'M5/340624' +export const N0 = 'N0/719700' +export const N1 = 'N1/322330' +export const N2 = 'N2/554905' +export const N3 = 'N3/279414' +export const N4 = 'N4/223549' +export const N5 = 'N5/106430' +export const O0 = 'O0/439753' +export const O1 = 'O1/184934' +export const O2 = 'O2/163117' +export const O3 = 'O3/801944' +export const O4 = 'O4/769058' +export const O5 = 'O5/682431' +export const P0 = 'P0/312289' +export const P1 = 'P1/708697' +export const P2 = 'P2/085809' +export const P3 = 'P3/664012' +export const P4 = 'P4/515888' +export const P5 = 'P5/973781' +export const Q0 = 'Q0/322861' +export const Q1 = 'Q1/010908' +export const Q2 = 'Q2/786194' +export const Q3 = 'Q3/614951' +export const Q4 = 'Q4/915803' +export const Q5 = 'Q5/475163' +export const R0 = 'R0/874630' +export const R1 = 'R1/430647' +export const R2 = 'R2/767178' +export const R3 = 'R3/943288' +export const R4 = 'R4/582084' +export const R5 = 'R5/501429' +export const S0 = 'S0/275258' +export const S1 = 'S1/739500' +export const S2 = 'S2/449586' +export const S3 = 'S3/891280' +export const S4 = 'S4/156946' +export const S5 = 'S5/027482' +export const T0 = 'T0/515259' +export const T1 = 'T1/898487' +export const T2 = 'T2/102538' +export const T3 = 'T3/666778' +export const T4 = 'T4/976512' +export const T5 = 'T5/843268' +export const U0 = 'U0/948132' +export const U1 = 'U1/844531' +export const U2 = 'U2/428499' +export const U3 = 'U3/676721' +export const U4 = 'U4/746122' +export const U5 = 'U5/758627' +export const V0 = 'V0/625208' +export const V1 = 'V1/894664' +export const V2 = 'V2/449156' +export const V3 = 'V3/800489' +export const V4 = 'V4/715514' +export const V5 = 'V5/777528' +export const W0 = 'W0/543856' +export const W1 = 'W1/610464' +export const W2 = 'W2/735768' +export const W3 = 'W3/268620' +export const W4 = 'W4/542722' +export const W5 = 'W5/515212' +export const X0 = 'X0/358710' +export const X1 = 'X1/930435' +export const X2 = 'X2/229496' +export const X3 = 'X3/642411' +export const X4 = 'X4/792973' +export const X5 = 'X5/997958' +export const Y0 = 'Y0/224673' +export const Y1 = 'Y1/383255' +export const Y2 = 'Y2/036710' +export const Y3 = 'Y3/941868' +export const Y4 = 'Y4/989940' +export const Y5 = 'Y5/885038' +export const Z0 = 'Z0/660512' +export const Z1 = 'Z1/946648' +export const Z2 = 'Z2/470347' +export const Z3 = 'Z3/744138' +export const Z4 = 'Z4/679676' +export const Z5 = 'Z5/904085' diff --git a/packages/repo/tests/covering-proofs.test.ts b/packages/repo/tests/covering-proofs.test.ts new file mode 100644 index 00000000000..b0a6d516c9c --- /dev/null +++ b/packages/repo/tests/covering-proofs.test.ts @@ -0,0 +1,84 @@ +import { CID } from 'multiformats' +import { MST } from '../src/mst' +import { MemoryBlockstore } from '../src/storage' +import * as k from './_keys' + +describe('covering proofs', () => { + /** + * + * * * + * _________|________ ____|____ + * | | | | | | | | + * * b __*__ f * -> __*__ d __*__ + * | | | | | | | | | | + * a c e g * b * * f * + * | | | | + * a c e g + * + * + * + */ + it('two deep split ', async () => { + const storage = new MemoryBlockstore() + const cid = CID.parse( + 'bafyreie5cvv4h45feadgeuwhbcutmh6t2ceseocckahdoe6uat64zmz454', + ) + + let mst = await MST.create(storage) + mst = await mst.add(k.A0, cid) + mst = await mst.add(k.B1, cid) + mst = await mst.add(k.C0, cid) + mst = await mst.add(k.E0, cid) + mst = await mst.add(k.F1, cid) + mst = await mst.add(k.G0, cid) + + const pointerBeforeOp = await mst.getPointer() + + mst = await mst.add(k.D2, cid) + const proof = await mst.getCoveringProof(k.D2) + + const proofStorage = new MemoryBlockstore(proof) + let proofMst = await MST.load(proofStorage, await mst.getPointer()) + proofMst = await proofMst.delete(k.D2) + const pointerAfterInvert = await proofMst.getPointer() + expect(pointerAfterInvert.equals(pointerBeforeOp)).toBe(true) + }) + + /** + * + * * * + * _____|_____ ____|____ + * | | | | | | | + * a b d e -> * c * + * | | + * __*__ __*__ + * | | | | + * a b d e + * + * + * + */ + it('two deep leafless splits ', async () => { + const storage = new MemoryBlockstore() + const cid = CID.parse( + 'bafyreie5cvv4h45feadgeuwhbcutmh6t2ceseocckahdoe6uat64zmz454', + ) + + let mst = await MST.create(storage) + mst = await mst.add(k.A0, cid) + mst = await mst.add(k.B0, cid) + mst = await mst.add(k.D0, cid) + mst = await mst.add(k.E0, cid) + + const pointerBeforeOp = await mst.getPointer() + + mst = await mst.add(k.C2, cid) + const proof = await mst.getCoveringProof(k.C2) + + const proofStorage = new MemoryBlockstore(proof) + let proofMst = await MST.load(proofStorage, await mst.getPointer()) + proofMst = await proofMst.delete(k.C2) + const pointerAfterInvert = await proofMst.getPointer() + expect(pointerAfterInvert.equals(pointerBeforeOp)).toBe(true) + }) +})