Browse Source

Fix serialization of negative BigDecimal values!

We've never needed this before but now it's fixed.
Added corresponding +ve & -ve tests just to make sure.

Only actual use-case that comes to mind is cancelling reward-share.
pull/67/head
catbref 5 years ago
parent
commit
a68caa2de1
  1. 8
      src/main/java/org/qortal/utils/Serialization.java
  2. 30
      src/test/java/org/qortal/test/SerializationTests.java

8
src/main/java/org/qortal/utils/Serialization.java

@ -7,6 +7,7 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import org.qortal.transform.TransformationException;
import org.qortal.transform.Transformer;
@ -28,7 +29,14 @@ public class Serialization {
// (At least until the BigDecimal XmlAdapter works - see data/package-info.java)
byte[] amountBytes = amount.setScale(8).unscaledValue().toByteArray();
byte[] output = new byte[length];
// To retain sign of 'amount', we might need to explicitly fill 'output' with leading 1s
if (amount.signum() == -1)
// Negative values: fill output with 1s
Arrays.fill(output, (byte) 0xff);
System.arraycopy(amountBytes, 0, output, length - amountBytes.length, amountBytes.length);
return output;
}

30
src/test/java/org/qortal/test/SerializationTests.java

@ -12,6 +12,7 @@ import org.qortal.transaction.Transaction;
import org.qortal.transform.TransformationException;
import org.qortal.transform.transaction.TransactionTransformer;
import org.qortal.utils.Base58;
import org.qortal.utils.Serialization;
import com.google.common.hash.HashCode;
@ -19,6 +20,9 @@ import io.druid.extendedset.intset.ConciseSet;
import static org.junit.Assert.*;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
@ -142,4 +146,30 @@ public class SerializationTests extends Common {
}
}
@Test
public void testPositiveBigDecimal() throws IOException {
BigDecimal amount = new BigDecimal("123.4567").setScale(8);
byte[] bytes = Serialization.serializeBigDecimal(amount);
assertEquals("Serialized BigDecimal should be 8 bytes long", 8, bytes.length);
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
BigDecimal newAmount = Serialization.deserializeBigDecimal(byteBuffer);
assertEqualBigDecimals("Deserialized BigDecimal has incorrect value", amount, newAmount);
}
@Test
public void testNegativeBigDecimal() throws IOException {
BigDecimal amount = new BigDecimal("-1.23").setScale(8);
byte[] bytes = Serialization.serializeBigDecimal(amount);
assertEquals("Serialized BigDecimal should be 8 bytes long", 8, bytes.length);
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
BigDecimal newAmount = Serialization.deserializeBigDecimal(byteBuffer);
assertEqualBigDecimals("Deserialized BigDecimal has incorrect value", amount, newAmount);
}
}
Loading…
Cancel
Save