mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-12 10:15:52 +00:00
Fixed VarInt serialization bug for the 0xffffffff number. Fixed VarInt sizeOf bug for the 0xffffffff number and added tests for VarInt edge cases.
The 4294967295 number (0xffffffff) was incorrectly serialized because the UnsignedInteger.MAX_VALUE.longValue() helper returned 4294967295 instead of expected 4294967296. The VarInt.sizeOf() incorrectly returned 9 instead of 5 for the 4294967295 (0xffffffff) number. See https://en.bitcoin.it/wiki/Protocol_specification#Variable_length_integer
This commit is contained in:
parent
ae3acdfefd
commit
3dfaf54e28
@ -185,6 +185,13 @@ public class Utils {
|
||||
return UnsignedLongs.compare(n1, n2) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Work around lack of unsigned types in Java.
|
||||
*/
|
||||
public static boolean isLessThanOrEqualToUnsigned(long n1, long n2) {
|
||||
return UnsignedLongs.compare(n1, n2) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hex encoding used throughout the framework. Use with HEX.encode(byte[]) or HEX.decode(CharSequence).
|
||||
*/
|
||||
|
@ -16,9 +16,8 @@
|
||||
|
||||
package com.google.bitcoin.core;
|
||||
|
||||
import com.google.common.primitives.UnsignedInteger;
|
||||
|
||||
import static com.google.bitcoin.core.Utils.isLessThanUnsigned;
|
||||
import static com.google.bitcoin.core.Utils.isLessThanOrEqualToUnsigned;
|
||||
|
||||
/**
|
||||
* A variable-length encoded integer using Satoshis encoding.
|
||||
@ -88,9 +87,9 @@ public class VarInt {
|
||||
public static int sizeOf(long value) {
|
||||
if (isLessThanUnsigned(value, 253))
|
||||
return 1;
|
||||
else if (isLessThanUnsigned(value, 65536))
|
||||
else if (isLessThanOrEqualToUnsigned(value, 0xFFFFL))
|
||||
return 3; // 1 marker + 2 data bytes
|
||||
else if (isLessThanUnsigned(value, UnsignedInteger.MAX_VALUE.longValue()))
|
||||
else if (isLessThanOrEqualToUnsigned(value, 0xFFFFFFFFL))
|
||||
return 5; // 1 marker + 4 data bytes
|
||||
else
|
||||
return 9; // 1 marker + 8 data bytes
|
||||
@ -99,9 +98,9 @@ public class VarInt {
|
||||
public byte[] encode() {
|
||||
if (isLessThanUnsigned(value, 253)) {
|
||||
return new byte[]{(byte) value};
|
||||
} else if (isLessThanUnsigned(value, 65536)) {
|
||||
} else if (isLessThanOrEqualToUnsigned(value, 0xFFFFL)) {
|
||||
return new byte[]{(byte) 253, (byte) (value), (byte) (value >> 8)};
|
||||
} else if (isLessThanUnsigned(value, UnsignedInteger.MAX_VALUE.longValue())) {
|
||||
} else if (isLessThanOrEqualToUnsigned(value, 0xFFFFFFFFL)) {
|
||||
byte[] bytes = new byte[5];
|
||||
bytes[0] = (byte) 254;
|
||||
Utils.uint32ToByteArrayLE(value, bytes, 1);
|
||||
|
@ -33,6 +33,13 @@ public class VarIntTest extends TestCase {
|
||||
assertEquals(64000, new VarInt(a.encode(), 0).value);
|
||||
}
|
||||
|
||||
public void testShortFFFF() throws Exception {
|
||||
VarInt a = new VarInt(0xFFFFL);
|
||||
assertEquals(3, a.getSizeInBytes());
|
||||
assertEquals(3, a.encode().length);
|
||||
assertEquals(0xFFFFL, new VarInt(a.encode(), 0).value);
|
||||
}
|
||||
|
||||
public void testInts() throws Exception {
|
||||
VarInt a = new VarInt(0xAABBCCDDL);
|
||||
assertEquals(5, a.getSizeInBytes());
|
||||
@ -41,6 +48,14 @@ public class VarIntTest extends TestCase {
|
||||
assertEquals(0xAABBCCDDL, 0xFFFFFFFFL & new VarInt(bytes, 0).value);
|
||||
}
|
||||
|
||||
public void testIntFFFFFFFF() throws Exception {
|
||||
VarInt a = new VarInt(0xFFFFFFFFL);
|
||||
assertEquals(5, a.getSizeInBytes());
|
||||
assertEquals(5, a.encode().length);
|
||||
byte[] bytes = a.encode();
|
||||
assertEquals(0xFFFFFFFFL, 0xFFFFFFFFL & new VarInt(bytes, 0).value);
|
||||
}
|
||||
|
||||
public void testLong() throws Exception {
|
||||
VarInt a = new VarInt(0xCAFEBABEDEADBEEFL);
|
||||
assertEquals(9, a.getSizeInBytes());
|
||||
|
Loading…
x
Reference in New Issue
Block a user