Skip to content

Commit

Permalink
chore: fix json parsing
Browse files Browse the repository at this point in the history
Signed-off-by: nikolay <n.atanasow94@gmail.com>
  • Loading branch information
natanasow committed Jan 17, 2025
1 parent 5e9e1b1 commit fa9f894
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 8 deletions.
7 changes: 5 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/relay/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@
},
"dependencies": {
"@ethersproject/asm": "^5.7.0",
"@hashgraph/sdk": "^2.54.0-beta.1",
"@hashgraph/json-rpc-config-service": "file:../config-service",
"@hashgraph/sdk": "^2.54.0-beta.1",
"@keyvhq/core": "^1.6.9",
"axios": "^1.4.0",
"axios-retry": "^3.5.1",
Expand All @@ -60,6 +60,7 @@
"dotenv": "^16.0.0",
"ethers": "^6.7.0",
"find-config": "^1.0.0",
"json-bigint": "^1.0.0",
"keccak": "^3.0.2",
"keyv": "^4.2.2",
"keyv-file": "^0.3.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/relay/src/formatters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ const nanOrNumberTo0x = (input: number | BigNumber | bigint | null): string => {

const nanOrNumberInt64To0x = (input: number | BigNumber | bigint | null): string => {
// converting to string and then back to int is fixing a typescript warning
if (input && parseInt(input.toString()) < 0) {
if (input && Number(input) < 0) {
// the hex of a negative number can be obtained from the binary value of that number positive value
// the binary value needs to be negated and then to be incremented by 1

Expand Down
23 changes: 23 additions & 0 deletions packages/relay/src/lib/clients/mirrorNodeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { install as betterLookupInstall } from 'better-lookup';
import { ethers } from 'ethers';
import http from 'http';
import https from 'https';
import JSONBigInt from 'json-bigint';
import { Logger } from 'pino';
import { Histogram, Registry } from 'prom-client';

Expand Down Expand Up @@ -361,6 +362,28 @@ export class MirrorNodeClient {
if (pathLabel == MirrorNodeClient.GET_CONTRACTS_RESULTS_OPCODES) {
response = await this.web3Client.get<T>(path, axiosRequestConfig);
} else {
// JS supports up to 53 bits integers, once a number with more bits is converted to a js Number type, the initial value is already lost
// in order to fix that, we have to use a custom JSON parser that hooks up before
// the default axios JSON.parse conversion where the value will be rounded and lost
// JSONBigInt reads the string representation of received JSON and formats each number to BigNumber
axiosRequestConfig['transformResponse'] = [
(data) => {
// if the data is not valid, just return it to stick to the current behaviour
if (data) {
try {
// try to parse it, if the json is valid, numbers within it will be converted
// this case will happen on almost every GET mirror node call
return JSONBigInt.parse(data);
} catch (e) {
// in some unit tests, the mocked returned json is not property formatted
// so we have to preprocess it here with JSON.stringify()
return JSONBigInt.parse(JSON.stringify(data));

Check warning on line 380 in packages/relay/src/lib/clients/mirrorNodeClient.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/clients/mirrorNodeClient.ts#L380

Added line #L380 was not covered by tests
}
}

return data;

Check warning on line 384 in packages/relay/src/lib/clients/mirrorNodeClient.ts

View check run for this annotation

Codecov / codecov/patch

packages/relay/src/lib/clients/mirrorNodeClient.ts#L384

Added line #L384 was not covered by tests
},
];
response = await this.restClient.get<T>(path, axiosRequestConfig);
}
} else {
Expand Down
59 changes: 55 additions & 4 deletions packages/relay/tests/lib/formatters.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -408,11 +408,62 @@ describe('Formatters', () => {
it('should return 0x0 for NaN input', () => {
expect(nanOrNumberInt64To0x(NaN)).to.equal('0x0');
});
it('should convert a valid number', () => {
expect(nanOrNumberInt64To0x(593)).to.equal('0x251');
it('should convert negative int64 number (2 digits)', () => {
expect(nanOrNumberInt64To0x(BigInt('-10'))).to.equal('0xfffffffffffffff6');
});
it('should convert a valid negative int64 number', () => {
expect(nanOrNumberInt64To0x(-10)).to.equal('0xfffffffffffffff6');
it('should convert negative int64 number (6 digits)', () => {
expect(nanOrNumberInt64To0x(BigInt('-851969'))).to.equal('0xfffffffffff2ffff');
});
it('should convert negative int64 number (19 digits -6917529027641081857)', () => {
expect(nanOrNumberInt64To0x(BigInt('-6917529027641081857'))).to.equal('0x9fffffffffffffff');
});
it('should convert negative int64 number (19 digits -9223372036586340353)', () => {
expect(nanOrNumberInt64To0x(BigInt('-9223372036586340353'))).to.equal('0x800000000fffffff');
});
it('should convert positive 10 bits number', () => {
expect(nanOrNumberInt64To0x(BigInt('593'))).to.equal('0x251');
});
it('should convert positive 50 bits number', () => {
expect(nanOrNumberInt64To0x(BigInt('844424930131967'))).to.equal('0x2ffffffffffff');
});
it('should convert positive 51 bits number', () => {
expect(nanOrNumberInt64To0x(BigInt('1970324836974591'))).to.equal('0x6ffffffffffff');
});
it('should convert positive 52 bits number', () => {
expect(nanOrNumberInt64To0x(BigInt('3096224743817215'))).to.equal('0xaffffffffffff');
});
it('should convert positive 53 bits number', () => {
expect(nanOrNumberInt64To0x(BigInt('9007199254740991'))).to.equal('0x1fffffffffffff');
});
it('should convert positive 54 bits number', () => {
expect(nanOrNumberInt64To0x(BigInt('13510798882111487'))).to.equal('0x2fffffffffffff');
});
it('should convert positive 55 bits number', () => {
expect(nanOrNumberInt64To0x(BigInt('31525197391593471'))).to.equal('0x6fffffffffffff');
});
it('should convert positive 56 bits number', () => {
expect(nanOrNumberInt64To0x(BigInt('49539595901075455'))).to.equal('0xafffffffffffff');
});
it('should convert positive 57 bits number', () => {
expect(nanOrNumberInt64To0x(BigInt('144115188075855871'))).to.equal('0x1ffffffffffffff');
});
it('should convert positive 58 bits number', () => {
expect(nanOrNumberInt64To0x(BigInt('216172782113783807'))).to.equal('0x2ffffffffffffff');
});
it('should convert positive 59 bits number', () => {
expect(nanOrNumberInt64To0x(BigInt('504403158265495551'))).to.equal('0x6ffffffffffffff');
});
it('should convert positive 60 bits number', () => {
expect(nanOrNumberInt64To0x(BigInt('792633534417207295'))).to.equal('0xaffffffffffffff');
});
it('should convert positive 61 bits number', () => {
expect(nanOrNumberInt64To0x(BigInt('2305843009213693951'))).to.equal('0x1fffffffffffffff');
});
it('should convert positive 62 bits number', () => {
expect(nanOrNumberInt64To0x(BigInt('3458764513820540927'))).to.equal('0x2fffffffffffffff');
});
it('should convert positive 63 bits number', () => {
expect(nanOrNumberInt64To0x(BigInt('8070450532247928831'))).to.equal('0x6fffffffffffffff');
});
});

Expand Down

0 comments on commit fa9f894

Please sign in to comment.