3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-14 19:25:51 +00:00

Use Utils.uint*() and Utils.readUint*() methods for all remaining instances where we still did the bit stuffing manually.

This commit is contained in:
Andreas Schildbach 2018-02-18 18:19:27 +01:00
parent aa593f46cd
commit b455ebc635
12 changed files with 98 additions and 93 deletions

View File

@ -28,8 +28,6 @@ import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import static org.bitcoinj.core.Utils.uint32ToByteStreamLE;
import static org.bitcoinj.core.Utils.uint64ToByteStreamLE;
import static com.google.common.base.Preconditions.checkNotNull;
/**
@ -126,9 +124,9 @@ public class PeerAddress extends ChildMessage {
//so assumes itself to be up. For a fuller implementation this needs to be dynamic only if
//the address refers to this client.
int secs = (int) (Utils.currentTimeSeconds());
uint32ToByteStreamLE(secs, stream);
Utils.uint32ToByteStreamLE(secs, stream);
}
uint64ToByteStreamLE(services, stream); // nServices.
Utils.uint64ToByteStreamLE(services, stream); // nServices.
// Java does not provide any utility to map an IPv4 address into IPv6 space, so we have to do it by hand.
byte[] ipBytes = addr.getAddress();
if (ipBytes.length == 4) {
@ -140,8 +138,7 @@ public class PeerAddress extends ChildMessage {
}
stream.write(ipBytes);
// And write out the port. Unlike the rest of the protocol, address and port is in big endian byte order.
stream.write((byte) (0xFF & port >> 8));
stream.write((byte) (0xFF & port));
Utils.uint16ToByteStreamBE(port, stream);
}
@Override
@ -162,7 +159,8 @@ public class PeerAddress extends ChildMessage {
} catch (UnknownHostException e) {
throw new RuntimeException(e); // Cannot happen.
}
port = ((0xFF & payload[cursor++]) << 8) | (0xFF & payload[cursor++]);
port = Utils.readUint16BE(payload, cursor);
cursor += 2;
// The 4 byte difference is the uint32 timestamp that was introduced in version 31402
length = protocolVersion > 31402 ? MESSAGE_SIZE : MESSAGE_SIZE - 4;
}

View File

@ -38,18 +38,12 @@ public class TransactionOutputChanges {
}
public TransactionOutputChanges(InputStream in) throws IOException {
int numOutsCreated = (in.read() & 0xFF) |
((in.read() & 0xFF) << 8) |
((in.read() & 0xFF) << 16) |
((in.read() & 0xFF) << 24);
int numOutsCreated = (int) Utils.readUint32FromStream(in);
txOutsCreated = new LinkedList<>();
for (int i = 0; i < numOutsCreated; i++)
txOutsCreated.add(new UTXO(in));
int numOutsSpent = (in.read() & 0xFF) |
((in.read() & 0xFF) << 8) |
((in.read() & 0xFF) << 16) |
((in.read() & 0xFF) << 24);
int numOutsSpent = (int) Utils.readUint32FromStream(in);
txOutsSpent = new LinkedList<>();
for (int i = 0; i < numOutsSpent; i++)
txOutsSpent.add(new UTXO(in));
@ -57,19 +51,13 @@ public class TransactionOutputChanges {
public void serializeToStream(OutputStream bos) throws IOException {
int numOutsCreated = txOutsCreated.size();
bos.write(0xFF & numOutsCreated);
bos.write(0xFF & (numOutsCreated >> 8));
bos.write(0xFF & (numOutsCreated >> 16));
bos.write(0xFF & (numOutsCreated >> 24));
Utils.uint32ToByteStreamLE(numOutsCreated, bos);
for (UTXO output : txOutsCreated) {
output.serializeToStream(bos);
}
int numOutsSpent = txOutsSpent.size();
bos.write(0xFF & numOutsSpent);
bos.write(0xFF & (numOutsSpent >> 8));
bos.write(0xFF & (numOutsSpent >> 16));
bos.write(0xFF & (numOutsSpent >> 24));
Utils.uint32ToByteStreamLE(numOutsSpent, bos);
for (UTXO output : txOutsSpent) {
output.serializeToStream(bos);
}

View File

@ -146,35 +146,22 @@ public class UTXO implements Serializable {
public void serializeToStream(OutputStream bos) throws IOException {
Utils.uint64ToByteStreamLE(BigInteger.valueOf(value.value), bos);
byte[] scriptBytes = script.getProgram();
bos.write(0xFF & scriptBytes.length);
bos.write(0xFF & scriptBytes.length >> 8);
bos.write(0xFF & (scriptBytes.length >> 16));
bos.write(0xFF & (scriptBytes.length >> 24));
Utils.uint32ToByteStreamLE(scriptBytes.length, bos);
bos.write(scriptBytes);
bos.write(hash.getBytes());
Utils.uint32ToByteStreamLE(index, bos);
bos.write(0xFF & (height));
bos.write(0xFF & (height >> 8));
bos.write(0xFF & (height >> 16));
bos.write(0xFF & (height >> 24));
Utils.uint32ToByteStreamLE(height, bos);
bos.write(new byte[] { (byte)(coinbase ? 1 : 0) });
}
public void deserializeFromStream(InputStream in) throws IOException {
byte[] valueBytes = new byte[8];
if (in.read(valueBytes, 0, 8) != 8)
throw new EOFException();
value = Coin.valueOf(Utils.readInt64(valueBytes, 0));
int scriptBytesLength = ((in.read() & 0xFF)) |
((in.read() & 0xFF) << 8) |
((in.read() & 0xFF) << 16) |
((in.read() & 0xFF) << 24);
int scriptBytesLength = (int) Utils.readUint32FromStream(in);
byte[] scriptBytes = new byte[scriptBytesLength];
if (in.read(scriptBytes) != scriptBytesLength)
throw new EOFException();
@ -190,10 +177,7 @@ public class UTXO implements Serializable {
throw new EOFException();
index = Utils.readUint32(indexBytes, 0);
height = ((in.read() & 0xFF)) |
((in.read() & 0xFF) << 8) |
((in.read() & 0xFF) << 16) |
((in.read() & 0xFF) << 24);
height = (int) Utils.readUint32FromStream(in);
byte[] coinbaseByte = new byte[1];
in.read(coinbaseByte);

View File

@ -18,6 +18,7 @@
package org.bitcoinj.core;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.text.DateFormat;
@ -88,12 +89,10 @@ public class Utils {
return dest;
}
/** Write 4 bytes to the byte array (starting at the offset) as unsigned 32-bit integer in big endian format. */
public static void uint32ToByteArrayBE(long val, byte[] out, int offset) {
out[offset] = (byte) (0xFF & (val >> 24));
out[offset + 1] = (byte) (0xFF & (val >> 16));
out[offset + 2] = (byte) (0xFF & (val >> 8));
out[offset + 3] = (byte) (0xFF & val);
/** Write 2 bytes to the byte array (starting at the offset) as unsigned 16-bit integer in little endian format. */
public static void uint16ToByteArrayLE(int val, byte[] out, int offset) {
out[offset] = (byte) (0xFF & val);
out[offset + 1] = (byte) (0xFF & (val >> 8));
}
/** Write 4 bytes to the byte array (starting at the offset) as unsigned 32-bit integer in little endian format. */
@ -104,6 +103,14 @@ public class Utils {
out[offset + 3] = (byte) (0xFF & (val >> 24));
}
/** Write 4 bytes to the byte array (starting at the offset) as unsigned 32-bit integer in big endian format. */
public static void uint32ToByteArrayBE(long val, byte[] out, int offset) {
out[offset] = (byte) (0xFF & (val >> 24));
out[offset + 1] = (byte) (0xFF & (val >> 16));
out[offset + 2] = (byte) (0xFF & (val >> 8));
out[offset + 3] = (byte) (0xFF & val);
}
/** Write 8 bytes to the byte array (starting at the offset) as signed 64-bit integer in little endian format. */
public static void int64ToByteArrayLE(long val, byte[] out, int offset) {
out[offset] = (byte) (0xFF & val);
@ -116,6 +123,18 @@ public class Utils {
out[offset + 7] = (byte) (0xFF & (val >> 56));
}
/** Write 2 bytes to the output stream as unsigned 16-bit integer in little endian format. */
public static void uint16ToByteStreamLE(int val, OutputStream stream) throws IOException {
stream.write((int) (0xFF & val));
stream.write((int) (0xFF & (val >> 8)));
}
/** Write 2 bytes to the output stream as unsigned 16-bit integer in big endian format. */
public static void uint16ToByteStreamBE(int val, OutputStream stream) throws IOException {
stream.write((int) (0xFF & (val >> 8)));
stream.write((int) (0xFF & val));
}
/** Write 4 bytes to the output stream as unsigned 32-bit integer in little endian format. */
public static void uint32ToByteStreamLE(long val, OutputStream stream) throws IOException {
stream.write((int) (0xFF & val));
@ -123,7 +142,15 @@ public class Utils {
stream.write((int) (0xFF & (val >> 16)));
stream.write((int) (0xFF & (val >> 24)));
}
/** Write 4 bytes to the output stream as unsigned 32-bit integer in big endian format. */
public static void uint32ToByteStreamBE(long val, OutputStream stream) throws IOException {
stream.write((int) (0xFF & (val >> 24)));
stream.write((int) (0xFF & (val >> 16)));
stream.write((int) (0xFF & (val >> 8)));
stream.write((int) (0xFF & val));
}
/** Write 8 bytes to the output stream as signed 64-bit integer in little endian format. */
public static void int64ToByteStreamLE(long val, OutputStream stream) throws IOException {
stream.write((int) (0xFF & val));
@ -150,6 +177,12 @@ public class Utils {
}
}
/** Parse 2 bytes from the byte array (starting at the offset) as unsigned 16-bit integer in little endian format. */
public static int readUint16(byte[] bytes, int offset) {
return (bytes[offset] & 0xff) |
((bytes[offset + 1] & 0xff) << 8);
}
/** Parse 4 bytes from the byte array (starting at the offset) as unsigned 32-bit integer in little endian format. */
public static long readUint32(byte[] bytes, int offset) {
return (bytes[offset] & 0xffl) |
@ -184,6 +217,28 @@ public class Utils {
(bytes[offset + 1] & 0xff);
}
/** Parse 2 bytes from the stream as unsigned 16-bit integer in little endian format. */
public static int readUint16FromStream(InputStream is) {
try {
return (is.read() & 0xff) |
((is.read() & 0xff) << 8);
} catch (IOException x) {
throw new RuntimeException(x);
}
}
/** Parse 4 bytes from the stream as unsigned 32-bit integer in little endian format. */
public static long readUint32FromStream(InputStream is) {
try {
return (is.read() & 0xffl) |
((is.read() & 0xffl) << 8) |
((is.read() & 0xffl) << 16) |
((is.read() & 0xffl) << 24);
} catch (IOException x) {
throw new RuntimeException(x);
}
}
/**
* Returns a copy of the given byte array in reverse order.
*/

View File

@ -45,7 +45,7 @@ public class VarInt {
value = first;
originallyEncodedSize = 1; // 1 data byte (8 bits)
} else if (first == 253) {
value = (0xFF & buf[offset + 1]) | ((0xFF & buf[offset + 2]) << 8);
value = Utils.readUint16(buf, offset + 1);
originallyEncodedSize = 3; // 1 marker + 2 data bytes (16 bits)
} else if (first == 254) {
value = Utils.readUint32(buf, offset + 1);
@ -96,7 +96,10 @@ public class VarInt {
case 1:
return new byte[]{(byte) value};
case 3:
return new byte[]{(byte) 253, (byte) (value), (byte) (value >> 8)};
bytes = new byte[3];
bytes[0] = (byte) 253;
Utils.uint16ToByteArrayLE((int) value, bytes, 1);
return bytes;
case 5:
bytes = new byte[5];
bytes[0] = (byte) 254;

View File

@ -17,6 +17,7 @@
package org.bitcoinj.net.discovery;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.core.Utils;
import javax.annotation.Nullable;
import java.net.InetAddress;
@ -104,10 +105,7 @@ public class SeedPeers implements PeerDiscovery {
private InetAddress convertAddress(int seed) throws UnknownHostException {
byte[] v4addr = new byte[4];
v4addr[0] = (byte) (0xFF & (seed));
v4addr[1] = (byte) (0xFF & (seed >> 8));
v4addr[2] = (byte) (0xFF & (seed >> 16));
v4addr[3] = (byte) (0xFF & (seed >> 24));
Utils.uint32ToByteArrayLE(seed, v4addr, 0);
return InetAddress.getByAddress(v4addr);
}

View File

@ -200,12 +200,12 @@ public class Script {
} else if (opcode == OP_PUSHDATA2) {
// Read a short, then read that many bytes of data.
if (bis.available() < 2) throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Unexpected end of script");
dataToRead = bis.read() | (bis.read() << 8);
dataToRead = Utils.readUint16FromStream(bis);
} else if (opcode == OP_PUSHDATA4) {
// Read a uint32, then read that many bytes of data.
// Though this is allowed, because its value cannot be > 520, it should never actually be used
if (bis.available() < 4) throw new ScriptException(ScriptError.SCRIPT_ERR_UNKNOWN_ERROR, "Unexpected end of script");
dataToRead = ((long)bis.read()) | (((long)bis.read()) << 8) | (((long)bis.read()) << 16) | (((long)bis.read()) << 24);
dataToRead = Utils.readUint32FromStream(bis);
}
ScriptChunk chunk;
@ -384,8 +384,7 @@ public class Script {
os.write(buf);
} else if (buf.length < 65536) {
os.write(OP_PUSHDATA2);
os.write(0xFF & (buf.length));
os.write(0xFF & (buf.length >> 8));
Utils.uint16ToByteStreamLE(buf.length, os);
os.write(buf);
} else {
throw new RuntimeException("Unimplemented");
@ -722,13 +721,9 @@ public class Script {
} else if (opcode == OP_PUSHDATA1) {
additionalBytes = (0xFF & inputScript[cursor]) + 1;
} else if (opcode == OP_PUSHDATA2) {
additionalBytes = ((0xFF & inputScript[cursor]) |
((0xFF & inputScript[cursor+1]) << 8)) + 2;
additionalBytes = Utils.readUint16(inputScript, cursor) + 2;
} else if (opcode == OP_PUSHDATA4) {
additionalBytes = ((0xFF & inputScript[cursor]) |
((0xFF & inputScript[cursor+1]) << 8) |
((0xFF & inputScript[cursor+1]) << 16) |
((0xFF & inputScript[cursor+1]) << 24)) + 4;
additionalBytes = (int) Utils.readUint32(inputScript, cursor) + 4;
}
if (!skip) {
try {

View File

@ -125,8 +125,7 @@ public class ScriptChunk {
} else if (opcode == OP_PUSHDATA2) {
checkState(data.length <= 0xFFFF);
stream.write(OP_PUSHDATA2);
stream.write(0xFF & data.length);
stream.write(0xFF & (data.length >> 8));
Utils.uint16ToByteStreamLE(data.length, stream);
} else if (opcode == OP_PUSHDATA4) {
checkState(data.length <= Script.MAX_SCRIPT_ELEMENT_SIZE);
stream.write(OP_PUSHDATA4);

View File

@ -668,10 +668,7 @@ public abstract class DatabaseFullPrunedBlockStore implements FullPrunedBlockSto
txOutChanges = bos.toByteArray();
} else {
int numTxn = undoableBlock.getTransactions().size();
bos.write(0xFF & numTxn);
bos.write(0xFF & (numTxn >> 8));
bos.write(0xFF & (numTxn >> 16));
bos.write(0xFF & (numTxn >> 24));
Utils.uint32ToByteStreamLE(numTxn, bos);
for (Transaction tx : undoableBlock.getTransactions())
tx.bitcoinSerialize(bos);
transactions = bos.toByteArray();
@ -805,11 +802,8 @@ public abstract class DatabaseFullPrunedBlockStore implements FullPrunedBlockSto
byte[] transactions = results.getBytes(2);
StoredUndoableBlock block;
if (txOutChanges == null) {
int offset = 0;
int numTxn = ((transactions[offset++] & 0xFF)) |
((transactions[offset++] & 0xFF) << 8) |
((transactions[offset++] & 0xFF) << 16) |
((transactions[offset++] & 0xFF) << 24);
int numTxn = (int) Utils.readUint32(transactions, 0);
int offset = 4;
List<Transaction> transactionList = new LinkedList<>();
for (int i = 0; i < numTxn; i++) {
Transaction tx = params.getDefaultSerializer().makeTransaction(transactions, offset);

View File

@ -38,6 +38,7 @@ import org.bitcoinj.core.Transaction;
import org.bitcoinj.core.TransactionOutputChanges;
import org.bitcoinj.core.UTXO;
import org.bitcoinj.core.UTXOProviderException;
import org.bitcoinj.core.Utils;
import org.bitcoinj.core.VerificationException;
import org.bitcoinj.script.Script;
import org.bitcoinj.script.ScriptException;
@ -513,10 +514,7 @@ public class LevelDBFullPrunedBlockStore implements FullPrunedBlockStore {
txOutChanges = bos.toByteArray();
} else {
int numTxn = undoableBlock.getTransactions().size();
bos.write((int) (0xFF & (numTxn >> 0)));
bos.write((int) (0xFF & (numTxn >> 8)));
bos.write((int) (0xFF & (numTxn >> 16)));
bos.write((int) (0xFF & (numTxn >> 24)));
Utils.uint32ToByteStreamLE(numTxn, bos);
for (Transaction tx : undoableBlock.getTransactions())
tx.bitcoinSerialize(bos);
transactions = bos.toByteArray();
@ -671,9 +669,8 @@ public class LevelDBFullPrunedBlockStore implements FullPrunedBlockStore {
int txSize = bb.getInt();
byte[] transactions = new byte[txSize];
bb.get(transactions);
int offset = 0;
int numTxn = ((transactions[offset++] & 0xFF) << 0) | ((transactions[offset++] & 0xFF) << 8)
| ((transactions[offset++] & 0xFF) << 16) | ((transactions[offset++] & 0xFF) << 24);
int numTxn = (int) Utils.readUint32(transactions, 0);
int offset = 4;
List<Transaction> transactionList = new LinkedList<>();
for (int i = 0; i < numTxn; i++) {
Transaction tx = new Transaction(params, transactions, offset);

View File

@ -181,10 +181,7 @@ public class PostgresFullPrunedBlockStore extends DatabaseFullPrunedBlockStore {
txOutChanges = bos.toByteArray();
} else {
int numTxn = undoableBlock.getTransactions().size();
bos.write(0xFF & numTxn);
bos.write(0xFF & (numTxn >> 8));
bos.write(0xFF & (numTxn >> 16));
bos.write(0xFF & (numTxn >> 24));
Utils.uint32ToByteStreamLE(numTxn, bos);
for (Transaction tx : undoableBlock.getTransactions())
tx.bitcoinSerialize(bos);
transactions = bos.toByteArray();

View File

@ -173,10 +173,7 @@ public class FullBlockTestGenerator {
public boolean add(Rule element) {
if (outStream != null && element instanceof BlockAndValidity) {
try {
outStream.write((int) (params.getPacketMagic() >>> 24));
outStream.write((int) (params.getPacketMagic() >>> 16));
outStream.write((int) (params.getPacketMagic() >>> 8));
outStream.write((int) params.getPacketMagic());
Utils.uint32ToByteStreamBE(params.getPacketMagic(), outStream);
byte[] block = ((BlockAndValidity)element).block.bitcoinSerialize();
byte[] length = new byte[4];
Utils.uint32ToByteArrayBE(block.length, length, 0);