Use signed 64-bit values for TransactionOutput.value.

The reference client (stupidly) does this, and we were incorrectly
de-serializing values from the reference client.
This commit is contained in:
Matt Corallo 2012-07-13 23:14:47 +02:00 committed by Mike Hearn
parent 8cd9cc11a4
commit 2aaa601293
3 changed files with 21 additions and 1 deletions

View File

@ -410,6 +410,11 @@ public abstract class Message implements Serializable {
return new Sha256Hash(hash);
}
long readInt64() {
long u = Utils.readInt64(bytes, cursor);
cursor += 8;
return u;
}
BigInteger readUint64() {
// Java does not have an unsigned 64 bit type. So scrape it off the wire then flip.

View File

@ -131,7 +131,11 @@ public class TransactionOutput extends ChildMessage implements Serializable {
}
protected void parseLite() {
value = readUint64();
// TODO: There is no reason to use BigInteger for values, they are always smaller than 21 million * COIN
// The only reason to use BigInteger would be to properly read values from the reference implementation, however
// the reference implementation uses signed 64-bit integers for its values as well (though it probably shouldn't)
long outputValue = readInt64();
value = BigInteger.valueOf(outputValue);
scriptLen = (int) readVarInt();
length = cursor - offset + scriptLen;
}

View File

@ -238,6 +238,17 @@ public class Utils {
((bytes[offset++] & 0xFFL) << 16) |
((bytes[offset] & 0xFFL) << 24);
}
public static long readInt64(byte[] bytes, int offset) {
return ((bytes[offset++] & 0xFFL) << 0) |
((bytes[offset++] & 0xFFL) << 8) |
((bytes[offset++] & 0xFFL) << 16) |
((bytes[offset++] & 0xFFL) << 24) |
((bytes[offset++] & 0xFFL) << 32) |
((bytes[offset++] & 0xFFL) << 40) |
((bytes[offset++] & 0xFFL) << 48) |
((bytes[offset] & 0xFFL) << 56);
}
public static long readUint32BE(byte[] bytes, int offset) {
return ((bytes[offset + 0] & 0xFFL) << 24) |