import ledgerFull38129 from './fixtures/ledger-full-38129.json' import ledgerFull40000 from './fixtures/ledger-full-40000.json' import { BytesList } from '../src/serdes/binary-serializer' import { ShaMap, ShaMapLeaf, ShaMapNode } from '../src/shamap' import { binary, HashPrefix } from '../src/coretypes' import { coreTypes, Hash256 } from '../src/types' function now() { return Number(Date.now()) / 1000 } const ZERO = '0000000000000000000000000000000000000000000000000000000000000000' function makeItem( indexArg: string, ): [ Hash256, { toBytesSink: (sink: BytesList) => void; hashPrefix: () => Uint8Array }, ] { let str = indexArg while (str.length < 64) { str += '0' } const index = Hash256.from(str) const item = { toBytesSink(sink: BytesList) { index.toBytesSink(sink) }, hashPrefix() { return Uint8Array.from([1, 3, 3, 7]) }, } return [index, item] } describe('ShaMap', () => { now() it('hashes to zero when empty', () => { const map = new ShaMap() expect(map.hash().toHex()).toBe(ZERO) }) it('creates the same hash no matter which order items are added', () => { let map = new ShaMap() const items = [ '0', '1', '11', '7000DE445E22CB9BB7E1717589FA858736BAA5FD192310E20000000000000000', '7000DE445E22CB9BB7E1717589FA858736BAA5FD192310E21000000000000000', '7000DE445E22CB9BB7E1717589FA858736BAA5FD192310E22000000000000000', '7000DE445E22CB9BB7E1717589FA858736BAA5FD192310E23000000000000000', '12', '122', ] // @ts-expect-error -- we are mocking nodes items.forEach((i) => map.addItem(...(makeItem(i) as ShaMapNode))) const h1 = map.hash() expect(h1.eq(h1)).toBe(true) map = new ShaMap() // @ts-expect-error -- we are mocking nodes items.reverse().forEach((i) => map.addItem(...(makeItem(i) as ShaMapNode))) expect(map.hash()).toEqual(h1) }) function factory(ledger: typeof ledgerFull38129 | typeof ledgerFull40000) { it(`recreate account state hash from ${ledger}`, () => { const map = new ShaMap() // const t = now(); const leafNodePrefix = HashPrefix.accountStateEntry ledger.accountState .map((e, i): ShaMapLeaf => { if (i > 1000 && i % 1000 === 0) { console.log(e.index) console.log(i) } const bytes = binary.serializeObject(e) return { index: coreTypes.Hash256.from(e.index), hashPrefix() { return leafNodePrefix }, toBytesSink(sink: BytesList) { sink.put(bytes) }, } as ShaMapLeaf }) .forEach((so: ShaMapLeaf) => map.addItem(so.index, so)) expect(map.hash().toHex()).toBe(ledger.account_hash) // console.log('took seconds: ', (now() - t)); }) } factory(ledgerFull38129) factory(ledgerFull40000) })