pmarches / jStellarAPI

java API for the stellar network
GNU Lesser General Public License v3.0
15 stars 3 forks source link

currency wire format #20

Open jargoman opened 10 years ago

jargoman commented 10 years ago

BinarySerializer, write currency.

Your code is correct but ripple rejects "floating point" values whose mantissa doesn't have 16 digits.

Lets say I want to send the value 1.23. Instead of the way you would expect. mantissa = 123; // unscaled value scale = 2; // or negative 2 in some implementations.

ripple expects it to be in wire format mantissa = 1230000000000000; scale = 15; // again may be -15

Both values are equal but only the second is accepted by rippled

1230000000000000 * 10 ^ -15 == 123 * 10 ^ -3; // statement is true

This is why the max and min scale have a difference of 16 80 - 96 = 16. and is also why 54 bits is allocated for the mantissa 9999999999999999 // 54 bit number.

It took me three days to figure out why your code was correct but returning "invalid currency value"

sublimator commented 10 years ago

A good way of testing implementations of binary parsing/reading is to implement a ShaMap and download some ledgers, calculating the transaction_hash. You can retrieve the transactions in binary form from rippled.

pmarches commented 10 years ago

Ah! That would explain why the C++ code iterates *10 and /10 to make the mantissa 16 digits long. I tried to be smart in avoiding that loop. Do you have a testcase or transaction that reproduces the problem?

sublimator: If we read the TX from the binary fromat, it actually computes the hash correctly, since the BigDecimal will be created with a 16 digit mantissa. The problem lies when we create a new BigDecimal from scratch that does not have the 16 digit mantissa.

Thank you to both of you for this,

Philippe

On Wed, Feb 26, 2014 at 1:45 PM, sublimator notifications@github.comwrote:

A good way of testing implementations of binary parsing/reading is to implement a ShaMap and download some ledgers, calculating the transaction_hash. You can retrieve the transactions in binary form from rippled.

Reply to this email directly or view it on GitHubhttps://github.com/pmarches/jRippleAPI/issues/20#issuecomment-36181238 .

sublimator commented 10 years ago

You can load from the rippled json too (for sanity testing)

sublimator commented 10 years ago

Actually a guy on the ripple forum posted a heap of full ledgers