-
Notifications
You must be signed in to change notification settings - Fork 188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for bignumbers #17
Add support for bignumbers #17
Conversation
37adb4c
to
64b4182
Compare
@pedrobranco can you add a test for this? Also, have you considered simply using a reviver function instead, as supported by |
Yes.
Already tried the reviver function, but already returns the value without the correct precision. > JSON.parse('{ "value": 150000000000000.00000000000000001 }', (k,v) => { console.log(k,v)})
value 150000000000000
{} |
What's the difference between this and https://www.npmjs.com/package/json-bigint or https://github.com/josdejong/lossless-json? |
IMO json-bigint-string is less intrusive by parsing only the unsupported values as string. const LosslessJSON = require('lossless-json');
let text = '{"normal":2.3,"long":123456789012345678901,"big":2.3e+500}';
let json = LosslessJSON.parse(text);
/*
{ normal: { [Number: 2.3] value: '2.3', type: 'LosslessNumber', isLosslessNumber: true },
long:
r {
value: '123456789012345678901',
type: 'LosslessNumber',
isLosslessNumber: true },
big:
r {
value: '2.3e+500',
type: 'LosslessNumber',
isLosslessNumber: true } }
*/
json.normal === 2.3 // false
let originalJson = JSON.parse(text); // { normal: 2.3, long: 123456789012345680000, big: Infinity }
originalJson.normal === 2.3 // true WDYT? |
After digging a bit, I think we can use const JSONBigInt = require('json-bigint')({ storeAsString: true, strict: true }); This qualifies for a breaking change so this would need to come in a form of a major version. |
package.json
Outdated
@@ -39,6 +39,7 @@ | |||
}, | |||
"dependencies": { | |||
"bluebird": "^3.1.1", | |||
"json-bigint-string": "^1.0.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Switch to json-bigint
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove dist/ files, as they are generated during the release phase.
@@ -118,7 +118,8 @@ class Client { | |||
|
|||
return this.request.postAsync({ | |||
auth: _.pickBy(this.auth, _.identity), | |||
body, | |||
body: JSON.stringify(body), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should make it clear that if users of the client want to keep precision, this should send those values as strings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -199,7 +199,7 @@ describe('Client', () => { | |||
it('should return the proof-of-work difficulty', async () => { | |||
const difficulty = await new Client(config.bitcoind).getDifficulty(); | |||
|
|||
difficulty.should.be.a.Number(); | |||
difficulty.should.be.a.String(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you rebase as this has been fixed already?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be unrelated to the changes on this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are parsing big numbers as String
this method will now return the result as a String
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is difficulty a big number?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
@pedrobranco can you rebase please? |
64b4182
to
2540d58
Compare
I would like to release this on the next major @pedrobranco. |
2540d58
to
0b1c732
Compare
docker-compose.yml
Outdated
@@ -10,7 +10,7 @@ sut: | |||
- bitcoind-username-only | |||
|
|||
bitcoind: | |||
image: seegno/bitcoind:0.13-alpine | |||
image: seegno/bitcoind:0.13.0-alpine |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rebase?
src/parser.js
Outdated
@@ -5,6 +5,7 @@ | |||
|
|||
import RpcError from './errors/rpc-error'; | |||
import _ from 'lodash'; | |||
import jsonBigInt from 'json-bigint'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JSONBigInt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eslint rule triggers http://eslint.org/docs/rules/new-cap. Should we ignore it?
src/parser.js
Outdated
@@ -52,6 +53,9 @@ export default class Parser { | |||
throw new RpcError(response.statusCode); | |||
} | |||
|
|||
// Parsing the body with custom parser to support BigNumbers. | |||
body = jsonBigInt({ storeAsString: true }).parse(body); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you address the other comments? (e.g. strict?)
bba077c
to
0382821
Compare
@ruimarinho Rebased. |
README.md
Outdated
@@ -91,6 +91,10 @@ client.getInfo().then(([body, headers]) => console.log(body, headers)); | |||
const [body, headers] = await client.getInfo(); | |||
``` | |||
|
|||
### Floating point number precision in JavaScript | |||
|
|||
Due to [Javascript floating point precision](http://floating-point-gui.de/), to prevent precision loss when using `bitcoin-core` we should pass all big numbers (numbers with more than 15 significant digits) as string instead of using `Number` data type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JavaScript's
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Due to JavaScript's limited floating point precision, all big numbers (numbers with more than 15 significant digits) are returned as strings to prevent precision loss.
0382821
to
24f8649
Compare
+1 for using just string. |
824e5d8
to
3ee0621
Compare
3ee0621
to
9ca5caf
Compare
This PR adds support for parsing correctly values with more than 15 significant digits (as string).
Fixes the issue #16.