diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e781aa..ee2843c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +## Fixed +- `getRepr` and `getRefsDescriptor` now using level mask instead of level +- Cells with prunned branches hash and serialization fixes + ## [0.56.1] - 2024-02-27 ## Fixed diff --git a/src/boc/cell/__testdata__/block2.txt b/src/boc/cell/__testdata__/block2.txt new file mode 100644 index 0000000..096afc5 --- /dev/null +++ b/src/boc/cell/__testdata__/block2.txt @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/src/boc/cell/descriptor.ts b/src/boc/cell/descriptor.ts index f85bf8f..b6790da 100644 --- a/src/boc/cell/descriptor.ts +++ b/src/boc/cell/descriptor.ts @@ -11,8 +11,8 @@ import { Cell } from "../Cell"; import { CellType } from "../CellType"; import { bitsToPaddedBuffer } from "../utils/paddedBits"; -export function getRefsDescriptor(refs: Cell[], level: number, type: CellType) { - return refs.length + (type !== CellType.Ordinary ? 1 : 0) * 8 + level * 32; +export function getRefsDescriptor(refs: Cell[], levelMask: number, type: CellType) { + return refs.length + (type !== CellType.Ordinary ? 1 : 0) * 8 + levelMask * 32; } export function getBitsDescriptor(bits: BitString) { @@ -20,7 +20,7 @@ export function getBitsDescriptor(bits: BitString) { return Math.ceil(len / 8) + Math.floor(len / 8); } -export function getRepr(originalBits: BitString, bits: BitString, refs: Cell[], level: number, type: CellType) { +export function getRepr(originalBits: BitString, bits: BitString, refs: Cell[], level: number, levelMask: number, type: CellType) { // Allocate const bitsLen = Math.ceil(bits.length / 8); @@ -28,7 +28,7 @@ export function getRepr(originalBits: BitString, bits: BitString, refs: Cell[], // Write descriptors let reprCursor = 0; - repr[reprCursor++] = getRefsDescriptor(refs, level, type); + repr[reprCursor++] = getRefsDescriptor(refs, levelMask, type); repr[reprCursor++] = getBitsDescriptor(originalBits); // Write bits diff --git a/src/boc/cell/serialization.spec.ts b/src/boc/cell/serialization.spec.ts index 2d18f23..11e3361 100644 --- a/src/boc/cell/serialization.spec.ts +++ b/src/boc/cell/serialization.spec.ts @@ -223,6 +223,13 @@ describe('boc', () => { expect(cell.hash().toString('hex')).toBe(testCase.hash); }); + it('should deserialize block 2', () => { + let testCase = fs.readFileSync(__dirname + '/__testdata__/block2.txt', 'utf8'); + let cell = Cell.fromBase64(testCase); + + expect(cell.hash().toString('hex')).toBe('25e19f8c4574804a8cabade6bab736a27a67f4f6696a8a0feb93b3dfbfab7fcf'); + }); + it('should serialize boc with index', () => { let cell = beginCell() .storeUint(228, 32) diff --git a/src/boc/cell/serialization.ts b/src/boc/cell/serialization.ts index 1aad3cb..95bb491 100644 --- a/src/boc/cell/serialization.ts +++ b/src/boc/cell/serialization.ts @@ -222,7 +222,7 @@ export function deserializeBoc(src: Buffer) { } function writeCellToBuilder(cell: Cell, refs: number[], sizeBytes: number, to: BitBuilder) { - let d1 = getRefsDescriptor(cell.refs, cell.level(), cell.type); + let d1 = getRefsDescriptor(cell.refs, cell.mask.value, cell.type); let d2 = getBitsDescriptor(cell.bits); to.writeUint(d1, 8); to.writeUint(d2, 8); diff --git a/src/boc/cell/wonderCalculator.ts b/src/boc/cell/wonderCalculator.ts index 240ee8e..85a81c9 100644 --- a/src/boc/cell/wonderCalculator.ts +++ b/src/boc/cell/wonderCalculator.ts @@ -129,7 +129,7 @@ export function wonderCalculator(type: CellType, bits: BitString, refs: Cell[]): // Hash // - let repr = getRepr(bits, currentBits, refs, levelI, type); + let repr = getRepr(bits, currentBits, refs, levelI, levelMask.apply(levelI).value, type); let hash = sha256_sync(repr); //