From 5bbc8f67d47f3cba11830f028c3f5a71b1a3ca61 Mon Sep 17 00:00:00 2001 From: homura Date: Sat, 6 Jan 2024 10:35:46 +0800 Subject: [PATCH] fix(base)!: unexpected unpacked result in blockchain --- .changeset/rare-mugs-begin.md | 5 + packages/base/src/blockchain.ts | 31 +++-- packages/base/tests/deserialize.test.ts | 151 ++++++++++++------------ packages/molecule/tests/grammar.test.ts | 2 +- 4 files changed, 105 insertions(+), 84 deletions(-) create mode 100644 .changeset/rare-mugs-begin.md diff --git a/.changeset/rare-mugs-begin.md b/.changeset/rare-mugs-begin.md new file mode 100644 index 000000000..3de080bed --- /dev/null +++ b/.changeset/rare-mugs-begin.md @@ -0,0 +1,5 @@ +--- +"@ckb-lumos/base": minor +--- + +BREAKING CHANGE: unpacked number of blockchain.\*.unpack should be `Hexadecimal` instead of `number` or`BI` diff --git a/packages/base/src/blockchain.ts b/packages/base/src/blockchain.ts index 734e97863..5716bfce5 100644 --- a/packages/base/src/blockchain.ts +++ b/packages/base/src/blockchain.ts @@ -12,9 +12,22 @@ import { import { BytesCodec, FixedBytesCodec } from "@ckb-lumos/codec/lib/base"; import type * as api from "./api"; -import { BI } from "@ckb-lumos/bi"; +import { BI, BIish } from "@ckb-lumos/bi"; + +function asHexadecimal( + codec: FixedBytesCodec | FixedBytesCodec +): FixedBytesCodec { + return { + ...codec, + unpack: (value) => BI.from(codec.unpack(value)).toHexString(), + }; +} + +const Uint8 = asHexadecimal(number.Uint8); +const Uint32LE = asHexadecimal(number.Uint32LE); +const Uint64LE = asHexadecimal(number.Uint64LE); +const Uint128LE = asHexadecimal(number.Uint128LE); -const { Uint128LE, Uint8, Uint32LE, Uint64LE } = number; const { byteVecOf, option, table, vector, struct } = molecule; const { bytify, hexify } = bytes; @@ -121,15 +134,15 @@ export const HashType = createFixedBytesCodec({ byteLength: 1, pack: (type) => { // prettier-ignore - if (type === "type") return Uint8.pack(0b0000000_1); + if (type === "type") return number.Uint8.pack(0b0000000_1); // prettier-ignore - if (type === "data") return Uint8.pack(0b0000000_0); - if (type === "data1") return Uint8.pack(0b0000001_0); - if (type === "data2") return Uint8.pack(0b0000010_0); + if (type === "data") return number.Uint8.pack(0b0000000_0); + if (type === "data1") return number.Uint8.pack(0b0000001_0); + if (type === "data2") return number.Uint8.pack(0b0000010_0); throw new Error(`Invalid hash type: ${type}`); }, unpack: (buf) => { - const hashTypeBuf = Uint8.unpack(buf); + const hashTypeBuf = number.Uint8.unpack(buf); if (hashTypeBuf === 0b0000000_1) return "type"; if (hashTypeBuf === 0b0000000_0) return "data"; if (hashTypeBuf === 0b0000001_0) return "data1"; @@ -146,7 +159,7 @@ export const DepType = createFixedBytesCodec({ throw new Error(`Invalid dep type: ${type}`); }, unpack: (buf) => { - const depTypeBuf = Uint8.unpack(buf); + const depTypeBuf = number.Uint8.unpack(buf); if (depTypeBuf === 0) return "code"; if (depTypeBuf === 1) return "depGroup"; throw new Error(`Invalid dep type: ${depTypeBuf}`); @@ -417,7 +430,7 @@ export function transformHeaderCodecType(data: api.Header): HeaderCodecType { export function deTransformHeaderCodecType( data: HeaderUnpackResultType -): RawHeaderUnpackResultType & { nonce: BI; hash: string } { +): RawHeaderUnpackResultType & { nonce: string; hash: string } { return { timestamp: data.raw.timestamp, number: data.raw.number, diff --git a/packages/base/tests/deserialize.test.ts b/packages/base/tests/deserialize.test.ts index 4bbbdc147..3c37d8647 100644 --- a/packages/base/tests/deserialize.test.ts +++ b/packages/base/tests/deserialize.test.ts @@ -1,9 +1,10 @@ import JSBI from "jsbi"; -import { HashType, DepType } from "../src"; +import { HashType, DepType, Header } from "../src"; import test from "ava"; import * as blockchain from "../src/blockchain"; import type * as api from "../src/api"; import { BI } from "@ckb-lumos/bi"; +import { bytes } from "@ckb-lumos/codec"; test.before(() => { // override valueOf of jsbi to make it comparable under ava test evironment @@ -21,40 +22,41 @@ test("unpack script", (t) => { }; const data = "0x3d0000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce80108000000aabbccdd44332211"; - const unpacked = blockchain.Script.unpack(data); - t.deepEqual(value, unpacked); + + t.deepEqual(value, blockchain.Script.unpack(data)); + t.deepEqual(data, bytes.hexify(blockchain.Script.pack(value))); }); test("unpack outpoint", (t) => { - const value = { + const value: api.OutPoint = { txHash: "0x4565f957aa65ca5d094ede05cbeaedcee70f5a71200ae2e31b643d2952c929bc", - index: BI.from("0x03").toNumber(), + index: BI.from("0x03").toHexString(), }; const data = "0x4565f957aa65ca5d094ede05cbeaedcee70f5a71200ae2e31b643d2952c929bc03000000"; - const unpacked = blockchain.OutPoint.unpack(data); - t.deepEqual(unpacked, value); + t.deepEqual(value, blockchain.OutPoint.unpack(data)); + t.deepEqual(data, bytes.hexify(blockchain.OutPoint.pack(value))); }); test("unpack cellinput", (t) => { - const value = { - since: BI.from("0x60a0001234"), + const value: api.Input = { + since: "0x60a0001234", previousOutput: { txHash: "0xa98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a73da", - index: 16, + index: "0x10", }, }; const data = "0x341200a060000000a98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a73da10000000"; - const unpacked = blockchain.CellInput.unpack(data); - t.deepEqual(unpacked, value); + t.deepEqual(value, blockchain.CellInput.unpack(data)); + t.deepEqual(data, bytes.hexify(blockchain.CellInput.pack(value))); }); test("unpack celloutput", (t) => { - const value = { - capacity: BI.from("0x10"), + const value: api.Output = { + capacity: "0x10", lock: { codeHash: "0xa98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a73da", @@ -70,14 +72,14 @@ test("unpack celloutput", (t) => { }; const data = "0x8400000010000000180000004f000000100000000000000037000000100000003000000031000000a98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a73da0002000000123435000000100000003000000031000000a98c57135830e1b900000000f6c4b8870828199a786b26f09f7dec4bc27a73db0100000000"; - const unpacked = blockchain.CellOutput.unpack(data); - t.deepEqual(unpacked, value); + t.deepEqual(value, blockchain.CellOutput.unpack(data)); + t.deepEqual(data, bytes.hexify(blockchain.CellOutput.pack(value))); }); test("unpack celloutput without type", (t) => { - const value = { - capacity: BI.from("0x10"), + const value: api.Output = { + capacity: "0x10", lock: { codeHash: "0xa98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a73da", @@ -88,36 +90,37 @@ test("unpack celloutput without type", (t) => { }; const data = "0x4f00000010000000180000004f000000100000000000000037000000100000003000000031000000a98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a73da00020000001234"; - const unpacked = blockchain.CellOutput.unpack(data); - t.deepEqual(unpacked, value); + + t.deepEqual(value, blockchain.CellOutput.unpack(data)); + t.deepEqual(data, bytes.hexify(blockchain.CellOutput.pack(value))); }); test("unpack celldep", (t) => { - const value = { - depType: "code", + const value: api.CellDep = { + depType: "code" as DepType, outPoint: { txHash: "0xa98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a73da", - index: 17, + index: "0x11", }, }; const data = "0xa98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a73da1100000000"; - const unpacked = blockchain.CellDep.unpack(data); - t.deepEqual(unpacked, value); + t.deepEqual(value, blockchain.CellDep.unpack(data)); + t.deepEqual(data, bytes.hexify(blockchain.CellDep.pack(value))); }); test("unpack transaction", (t) => { - const value = { - version: 0, + const value: api.Transaction = { + version: "0x0", cellDeps: [ { depType: "code" as DepType, outPoint: { txHash: "0xa98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a7300", - index: 0, + index: "0x0", }, }, ], @@ -126,17 +129,17 @@ test("unpack transaction", (t) => { ], inputs: [ { - since: BI.from("0x10"), + since: "0x10", previousOutput: { txHash: "0xa98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a7301", - index: 2, + index: "0x2", }, }, ], outputs: [ { - capacity: BI.from("0x1234"), + capacity: "0x1234", lock: { codeHash: "0xa98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a7302", @@ -151,54 +154,54 @@ test("unpack transaction", (t) => { }; const data = "0x1f0100000c0000000f010000030100001c00000020000000490000006d0000009d000000f40000000000000001000000a98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a7300000000000001000000b39d53656421d1532dd995a0924441ca8f43052bc2b7740a0e814a488a8214d6010000001000000000000000a98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a73010200000057000000080000004f00000010000000180000004f000000341200000000000037000000100000003000000031000000a98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a7302000200000012340f0000000800000003000000abcdef10000000080000000400000031313131"; - const unpacked = blockchain.Transaction.unpack(data); - t.deepEqual(unpacked, value); + t.deepEqual(value, blockchain.Transaction.unpack(data)); + t.deepEqual(data, bytes.hexify(blockchain.Transaction.pack(value))); }); test("unpack header", (t) => { - const value = { - compactTarget: 439170196, - number: BI.from("0xfb1bc"), + const value: Header = { + compactTarget: "0x1a2d3494", + number: "0xfb1bc", parentHash: "0x3134874027b9b2b17391d2fa545344b10bd8b8c49d9ea47d55a447d01142b21b", - nonce: BI.from("0x449b385049af131a0000001584a00100"), - timestamp: BI.from("0x170aba663c3"), + nonce: "0x449b385049af131a0000001584a00100", + timestamp: "0x170aba663c3", transactionsRoot: "0x68a83c880eb942396d22020aa83343906986f66418e9b8a4488f2866ecc4e86a", proposalsHash: "0x0000000000000000000000000000000000000000000000000000000000000000", extraHash: "0x0000000000000000000000000000000000000000000000000000000000000000", - version: 0, - epoch: BI.from("0x7080612000287"), + version: "0x0", + epoch: "0x7080612000287", dao: "0x40b4d9a3ddc9e730736c7342a2f023001240f362253b780000b6ca2f1e790107", hash: "", }; const data = "0x0000000094342d1ac363a6ab70010000bcb10f000000000087020012060807003134874027b9b2b17391d2fa545344b10bd8b8c49d9ea47d55a447d01142b21b68a83c880eb942396d22020aa83343906986f66418e9b8a4488f2866ecc4e86a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040b4d9a3ddc9e730736c7342a2f023001240f362253b780000b6ca2f1e7901070001a084150000001a13af4950389b44"; - const unpacked = blockchain.Header.unpack(data); - t.deepEqual(unpacked, value); + t.deepEqual(value, blockchain.Header.unpack(data)); + t.deepEqual(data, bytes.hexify(blockchain.Header.pack(value))); }); test("unpack uncle block", (t) => { - const value = { + const value: api.UncleBlock = { header: { - compactTarget: 439170196, - number: BI.from("0xfb1bc"), + compactTarget: "0x1a2d3494", + number: "0xfb1bc", parentHash: "0x3134874027b9b2b17391d2fa545344b10bd8b8c49d9ea47d55a447d01142b21b", - nonce: BI.from("0x449b385049af131a0000001584a00100"), - timestamp: BI.from("0x170aba663c3"), + nonce: "0x449b385049af131a0000001584a00100", + timestamp: "0x170aba663c3", transactionsRoot: "0x68a83c880eb942396d22020aa83343906986f66418e9b8a4488f2866ecc4e86a", proposalsHash: "0x0000000000000000000000000000000000000000000000000000000000000000", extraHash: "0x0000000000000000000000000000000000000000000000000000000000000000", - version: 0, - epoch: BI.from("0x7080612000287"), + version: "0x0", + epoch: "0x7080612000287", dao: "0x40b4d9a3ddc9e730736c7342a2f023001240f362253b780000b6ca2f1e790107", hash: "", }, @@ -206,41 +209,41 @@ test("unpack uncle block", (t) => { }; const data = "0xf40000000c000000dc0000000000000094342d1ac363a6ab70010000bcb10f000000000087020012060807003134874027b9b2b17391d2fa545344b10bd8b8c49d9ea47d55a447d01142b21b68a83c880eb942396d22020aa83343906986f66418e9b8a4488f2866ecc4e86a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040b4d9a3ddc9e730736c7342a2f023001240f362253b780000b6ca2f1e7901070001a084150000001a13af4950389b440200000012345678901234567890abcdeabcdeabcdeabcde"; - const unpacked = blockchain.UncleBlock.unpack(data); - t.deepEqual(unpacked, value); + t.deepEqual(value, blockchain.UncleBlock.unpack(data)); + t.deepEqual(data, bytes.hexify(blockchain.UncleBlock.pack(value))); }); test("unpack block", (t) => { - const value = { + const value: api.Block = { header: { - compactTarget: 439170196, - number: BI.from("0xfb1bc"), + compactTarget: "0x1a2d3494", + number: "0xfb1bc", parentHash: "0x3134874027b9b2b17391d2fa545344b10bd8b8c49d9ea47d55a447d01142b21b", - nonce: BI.from("0x449b385049af131a0000001584a00100"), - timestamp: BI.from("0x170aba663c3"), + nonce: "0x449b385049af131a0000001584a00100", + timestamp: "0x170aba663c3", transactionsRoot: "0x68a83c880eb942396d22020aa83343906986f66418e9b8a4488f2866ecc4e86a", proposalsHash: "0x0000000000000000000000000000000000000000000000000000000000000000", extraHash: "0x0000000000000000000000000000000000000000000000000000000000000000", - version: 0, - epoch: BI.from("0x7080612000287"), + version: "0x0", + epoch: "0x7080612000287", dao: "0x40b4d9a3ddc9e730736c7342a2f023001240f362253b780000b6ca2f1e790107", hash: "", }, transactions: [ { - version: 0, + version: "0x0", cellDeps: [ { depType: "code" as DepType, outPoint: { txHash: "0xa98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a7300", - index: 0, + index: "0x0", }, }, ], @@ -249,17 +252,17 @@ test("unpack block", (t) => { ], inputs: [ { - since: BI.from("0x10"), + since: "0x10", previousOutput: { txHash: "0xa98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a7301", - index: 2, + index: "0x2", }, }, ], outputs: [ { - capacity: BI.from("0x1234"), + capacity: "0x1234", lock: { codeHash: "0xa98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a7302", @@ -278,44 +281,44 @@ test("unpack block", (t) => { }; const data = "0x2502000014000000e4000000e80000000d0200000000000094342d1ac363a6ab70010000bcb10f000000000087020012060807003134874027b9b2b17391d2fa545344b10bd8b8c49d9ea47d55a447d01142b21b68a83c880eb942396d22020aa83343906986f66418e9b8a4488f2866ecc4e86a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040b4d9a3ddc9e730736c7342a2f023001240f362253b780000b6ca2f1e7901070001a084150000001a13af4950389b440400000025010000080000001d0100000c0000000f010000030100001c00000020000000490000006d0000009d000000f40000000000000001000000a98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a7300000000000001000000b39d53656421d1532dd995a0924441ca8f43052bc2b7740a0e814a488a8214d6010000001000000000000000a98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a73010200000057000000080000004f00000010000000180000004f000000341200000000000037000000100000003000000031000000a98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a7302000200000012340f0000000800000003000000abcdef0e000000080000000200000011110200000012345678901234567890abcdeabcdeabcdeabcde"; - const unpacked = blockchain.Block.unpack(data); - t.deepEqual(unpacked, value); + t.deepEqual(value, blockchain.Block.unpack(data)); + t.deepEqual(data, bytes.hexify(blockchain.Block.pack(value))); }); test("serialize witness args", (t) => { - const value = { + const value: api.WitnessArgs = { lock: "0x1234", inputType: "0x4678", outputType: "0x2312", }; const data = "0x2200000010000000160000001c000000020000001234020000004678020000002312"; - const unpacked = blockchain.WitnessArgs.unpack(data); - t.deepEqual(unpacked, value); + t.deepEqual(value, blockchain.WitnessArgs.unpack(data)); + t.deepEqual(data, bytes.hexify(blockchain.WitnessArgs.pack(value))); }); test("unpack empty witness args", (t) => { - const value = { + const value: api.WitnessArgs = { lock: undefined, inputType: undefined, outputType: undefined, }; const data = "0x10000000100000001000000010000000"; - const unpacked = blockchain.WitnessArgs.unpack(data); - t.deepEqual(unpacked, value); + t.deepEqual(value, blockchain.WitnessArgs.unpack(data)); + t.deepEqual(data, bytes.hexify(blockchain.WitnessArgs.pack(value))); }); test("unpack only one witness args", (t) => { - const value = { + const value: api.WitnessArgs = { lock: "0x1234", inputType: undefined, outputType: undefined, }; const data = "0x16000000100000001600000016000000020000001234"; - const unpacked = blockchain.WitnessArgs.unpack(data); - t.deepEqual(unpacked, value); + t.deepEqual(value, blockchain.WitnessArgs.unpack(data)); + t.deepEqual(data, bytes.hexify(blockchain.WitnessArgs.pack(value))); }); diff --git a/packages/molecule/tests/grammar.test.ts b/packages/molecule/tests/grammar.test.ts index 7f0a3788c..1a1359680 100644 --- a/packages/molecule/tests/grammar.test.ts +++ b/packages/molecule/tests/grammar.test.ts @@ -39,7 +39,7 @@ test("should parse sample with refs", (t) => { { txHash: "0xa98c57135830e1b91345948df6c4b8870828199a786b26f09f7dec4bc27a7300", - index: 1, + index: "0x1", }, ] );