From 9a85aaa109b6acbba8d548c13359577abb9be1ba Mon Sep 17 00:00:00 2001 From: Ildar Gumirov Date: Wed, 29 Nov 2023 20:27:36 +0100 Subject: [PATCH] fix: nftoken taxon calculation (#2590) Fix taxon calculation for NFTokenID ### Context of Change If NFToken taxon or serial is too big to be handled as number it could be calculated wrong. --- packages/xrpl/HISTORY.md | 3 ++ packages/xrpl/src/utils/parseNFTokenID.ts | 12 +++++++- .../xrpl/test/utils/parseNFTokenID.test.ts | 30 +++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/packages/xrpl/HISTORY.md b/packages/xrpl/HISTORY.md index bcb40447..5b016387 100644 --- a/packages/xrpl/HISTORY.md +++ b/packages/xrpl/HISTORY.md @@ -12,6 +12,9 @@ Subscribe to [the **xrpl-announce** mailing list](https://groups.google.com/g/xr ### Added * Support for `server_definitions` RPC +### Fixed +* Fix parseNFTokenID to return the correct taxon if large serial and (or) taxon were used + ## 2.13.0 (2023-10-18) ### Fixed diff --git a/packages/xrpl/src/utils/parseNFTokenID.ts b/packages/xrpl/src/utils/parseNFTokenID.ts index 3c253d15..0419b4f1 100644 --- a/packages/xrpl/src/utils/parseNFTokenID.ts +++ b/packages/xrpl/src/utils/parseNFTokenID.ts @@ -24,7 +24,17 @@ import { XrplError } from '../errors' */ function unscrambleTaxon(taxon: number, tokenSeq: number): number { /* eslint-disable no-bitwise -- XOR is part of the encode/decode scheme. */ - return (taxon ^ (384160001 * tokenSeq + 2459)) % 4294967296 + const seed = 384160001 + const increment = 2459 + const max = 4294967296 + + const scramble = new BigNumber(seed) + .multipliedBy(tokenSeq) + .modulo(max) + .plus(increment) + .modulo(max) + .toNumber() + return (taxon ^ scramble) >>> 0 /* eslint-enable no-bitwise */ } diff --git a/packages/xrpl/test/utils/parseNFTokenID.test.ts b/packages/xrpl/test/utils/parseNFTokenID.test.ts index f2f9cfb7..c265700b 100644 --- a/packages/xrpl/test/utils/parseNFTokenID.test.ts +++ b/packages/xrpl/test/utils/parseNFTokenID.test.ts @@ -19,6 +19,36 @@ describe('parseNFTokenID', function () { assertResultMatch(result, expected) }) + it('decode a valid NFTokenID with big taxon', function () { + const nftokenID = + '000000005EC8BC31F0415E5DD4A8AAAC3718249F8F27323C2EEE87B80000001E' + const result = parseNFTokenID(nftokenID) + const expected = { + NFTokenID: nftokenID, + Flags: 0, + TransferFee: 0, + Issuer: 'r9ewzMXVRAD9CjZQ6LTQ4P21vUUucDuqd4', + Taxon: 2147483649, + Sequence: 30, + } + assertResultMatch(result, expected) + }) + + it('decode a valid NFTokenID with big sequence', function () { + const nftokenID = + '00081388BE9E48FA0E6C95A3E970EB9503E3D3967E8DF95041FED82604D933AB' + const result = parseNFTokenID(nftokenID) + const expected = { + NFTokenID: nftokenID, + Flags: 8, + TransferFee: 5000, + Issuer: 'rJ4urHeGPr69TsC9TY9u8N965AdD7S3XEY', + Taxon: 96, + Sequence: 81343403, + } + assertResultMatch(result, expected) + }) + it('fail when given invalid NFTokenID', function () { assert.throws(() => { parseNFTokenID('ABCD')