-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Invalid scientific JNumbers handling #2879
Comments
52-bit precision is not enough for our 256-bit VM, but this value matches the reference implementation, see the neo-project/neo#2879. MaxIntegerPrec will be increased (or even removed) as soon as the ref. issue is resolved.
Related to #2498, btw. |
52-bit precision is not enough for our 256-bit VM, but this value matches the reference implementation, see the neo-project/neo#2879. MaxIntegerPrec will be increased (or even removed) as soon as the ref. issue is resolved.
52-bit precision is not enough for our 256-bit VM, but this value matches the reference implementation, see the neo-project/neo#2879. MaxIntegerPrec will be increased (or even removed) as soon as the ref. issue is resolved.
52-bit precision is not enough for our 256-bit VM, but this value matches the reference implementation, see the neo-project/neo#2879. MaxIntegerPrec will be increased (or even removed) as soon as the ref. issue is resolved.
52-bit precision is not enough for our 256-bit VM, but this value matches the reference implementation, see the neo-project/neo#2879. MaxIntegerPrec will be increased (or even removed) as soon as the ref. issue is resolved. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
for the first problem, had tested, still could not locate the problem, will keep trying. |
Test result in #2882 might indicate that floating-point is OK |
Well, the first problem is not actually a floating-point problem, it's a problem of parsing big numbers with some restricted predefined precision which gives the side-effects of |
52-bit precision is not enough for our 256-bit VM, but this value matches the reference implementation, see the neo-project/neo#2879. MaxIntegerPrec will be increased (or even removed) as soon as the ref. issue is resolved. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
The first problem seems caused by double's precision, since almost all number will convert to double first then to BigInteger. var num1 = 9.05e+28;
var num2 = (BigInteger)9.05e+28;
Console.WriteLine($"num double:{num1}");
Console.WriteLine($"num double to BigInteger:{num2}"); output: num double:9.05E+28
num double to BigInteger:90499999999999993918259200000 |
@Ashuaidehao U r right, need to use |
Describe the bug
The first problem
It's possible to pass some big number to a contract via JSON-serialized number and then deserialize it into Integer stackitem. For example, contract
RealtimePriceOracle
with0xbb054aaf5466e1bc49876c9eac747eddbac2ab6f
hash deployed on T5 testnet has methodupdatePrice
which accepts serialized set of prices. This method was invoked at block 2336911 of T5 testnet which caused the NeoGo and NeoC# nodes state diff (nspcc-dev/neo-go#3069). C# node successfuly handled the call while Go node failed to parse one of the provided JNumbers (2.8e+22
):After that, we have fixed our JNumbers parsing and allowed to parse scientific numbers like
2.8e+22
in nspcc-dev/neo-go#3073. After this fix, NeoGo state for block 2336911 matches the NeoC# node state which is OK.However, the new state difference appears after this fix at block 2342940@T5 due to the wollowing transaction processing:
As you can see, the same
updatePrice
method is called with the following set of arguments:[9.05e+28,1.871e+21,3.0366e+32,1e+30]
. The resulting stack after the invocation (which matches the price values stored in the contract storage) for the C# node is:And the resulting stack of the same invocation for NeoGo node is:
As you can see, the C# node stores the provided scientific numbers as floating point numbers and e.g. the
9.05e+28
input is being converted to"90499999999999993918259200000"
instead of the desired90500000000000000000000000000
. And the NeoGo node stores the provided scientific values as solid integers up to some precision. The maximum precision allowed for this "solid" parsing is restricted bybig.MaxPrec
setting we use in NeoGo while deserializeing these values. Thus, I consider there's some inaccuracy while processing the scientific numbers in the NeoC# node. We should probably consider restricting the maximum number that is allowed to be parsed from JSON and we should be sure that numbers under this constraint can be parsed as solid integers.The second problem
The second problem is that NeoC# node allows to parse floating-point numbers in a scientific notation. For examle, from a couple of following tests the first one will pass (which is OK), and the second one will also pass (which is not OK, because it's a floating point number in fact and this test should throw the FormatException):
To Reproduce
Steps to reproduce the behavior:
See the related NeoGo statediffs issue and PR: nspcc-dev/neo-go#3069, nspcc-dev/neo-go#3073.
Expected behavior
For the first problem, we have to provide the ability to parse from JSON exactly those numbers as were provided by the user in scientific notation up to some maximum precision value. I consider that we should forbid parsing numbers that are bigger than this max precision value.
For the second problem we have to forbit parsing floating-point numbers from scientific notation, like it is done for simple floating-point numbers.
Platform:
Additional context
However, we may consider disallowing scientific numbers parsing at all. It's a point of discussion.
The text was updated successfully, but these errors were encountered: