forked from Qortal/qortal
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.
This commit is contained in:
parent
3470b8bf57
commit
a68caa2de1
@ -7,6 +7,7 @@ import java.math.BigDecimal;
|
|||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.qortal.transform.TransformationException;
|
import org.qortal.transform.TransformationException;
|
||||||
import org.qortal.transform.Transformer;
|
import org.qortal.transform.Transformer;
|
||||||
@ -28,7 +29,14 @@ public class Serialization {
|
|||||||
// (At least until the BigDecimal XmlAdapter works - see data/package-info.java)
|
// (At least until the BigDecimal XmlAdapter works - see data/package-info.java)
|
||||||
byte[] amountBytes = amount.setScale(8).unscaledValue().toByteArray();
|
byte[] amountBytes = amount.setScale(8).unscaledValue().toByteArray();
|
||||||
byte[] output = new byte[length];
|
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);
|
System.arraycopy(amountBytes, 0, output, length - amountBytes.length, amountBytes.length);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import org.qortal.transaction.Transaction;
|
|||||||
import org.qortal.transform.TransformationException;
|
import org.qortal.transform.TransformationException;
|
||||||
import org.qortal.transform.transaction.TransactionTransformer;
|
import org.qortal.transform.transaction.TransactionTransformer;
|
||||||
import org.qortal.utils.Base58;
|
import org.qortal.utils.Base58;
|
||||||
|
import org.qortal.utils.Serialization;
|
||||||
|
|
||||||
import com.google.common.hash.HashCode;
|
import com.google.common.hash.HashCode;
|
||||||
|
|
||||||
@ -19,6 +20,9 @@ import io.druid.extendedset.intset.ConciseSet;
|
|||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
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…
Reference in New Issue
Block a user