Message: inline all read helpers

They were only calling through anyways.
This commit is contained in:
Andreas Schildbach 2023-03-29 16:57:08 +02:00
parent ce39967d83
commit bc035737d1
21 changed files with 81 additions and 119 deletions

View File

@ -49,7 +49,7 @@ public class AddressV1Message extends AddressMessage {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
final VarInt numAddressesVarInt = readVarInt();
final VarInt numAddressesVarInt = VarInt.read(payload);
int numAddresses = numAddressesVarInt.intValue();
// Guard against ultra large messages that will crash us.
if (numAddresses > MAX_ADDRESSES)

View File

@ -49,7 +49,7 @@ public class AddressV2Message extends AddressMessage {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
final VarInt numAddressesVarInt = readVarInt();
final VarInt numAddressesVarInt = VarInt.read(payload);
int numAddresses = numAddressesVarInt.intValue();
// Guard against ultra large messages that will crash us.
if (numAddresses > MAX_ADDRESSES)

View File

@ -22,6 +22,7 @@ import org.bitcoinj.base.Address;
import org.bitcoinj.base.Coin;
import org.bitcoinj.base.Sha256Hash;
import org.bitcoinj.base.VarInt;
import org.bitcoinj.base.internal.Buffers;
import org.bitcoinj.base.internal.TimeUtils;
import org.bitcoinj.base.internal.ByteUtils;
import org.bitcoinj.base.internal.InternalUtils;
@ -222,7 +223,7 @@ public class Block extends Message {
* Parse transactions from the block.
*/
protected void parseTransactions() throws ProtocolException {
VarInt numTransactionsVarInt = readVarInt();
VarInt numTransactionsVarInt = VarInt.read(payload);
int numTransactions = numTransactionsVarInt.intValue();
transactions = new ArrayList<>(Math.min(numTransactions, Utils.MAX_INITIAL_ARRAY_LENGTH));
for (int i = 0; i < numTransactions; i++) {
@ -237,14 +238,14 @@ public class Block extends Message {
protected void parse() throws BufferUnderflowException, ProtocolException {
// header
payload.mark();
version = readUint32();
prevBlockHash = readHash();
merkleRoot = readHash();
time = Instant.ofEpochSecond(readUint32());
difficultyTarget = readUint32();
nonce = readUint32();
version = ByteUtils.readUint32(payload);
prevBlockHash = Sha256Hash.read(payload);
merkleRoot = Sha256Hash.read(payload);
time = Instant.ofEpochSecond(ByteUtils.readUint32(payload));
difficultyTarget = ByteUtils.readUint32(payload);
nonce = ByteUtils.readUint32(payload);
payload.reset(); // read again from the mark for the hash
hash = Sha256Hash.wrapReversed(Sha256Hash.hashTwice(readBytes(HEADER_SIZE)));
hash = Sha256Hash.wrapReversed(Sha256Hash.hashTwice(Buffers.readBytes(payload, HEADER_SIZE)));
// transactions
if (payload.hasRemaining()) // otherwise this message is just a header

View File

@ -20,6 +20,7 @@ package org.bitcoinj.core;
import com.google.common.base.MoreObjects;
import org.bitcoinj.base.Sha256Hash;
import org.bitcoinj.base.VarInt;
import org.bitcoinj.base.internal.Buffers;
import org.bitcoinj.base.internal.ByteUtils;
import org.bitcoinj.crypto.ECKey;
import org.bitcoinj.script.Script;
@ -149,14 +150,14 @@ public class BloomFilter extends Message {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
data = readByteArray();
data = Buffers.readLengthPrefixedBytes(payload);
if (data.length > MAX_FILTER_SIZE)
throw new ProtocolException ("Bloom filter out of size range.");
hashFuncs = readUint32();
hashFuncs = ByteUtils.readUint32(payload);
if (hashFuncs > MAX_HASH_FUNCS)
throw new ProtocolException("Bloom filter hash function count out of range");
nTweak = readInt32();
nFlags = readByte();
nTweak = ByteUtils.readInt32(payload);
nFlags = payload.get();
}
/**

View File

@ -21,7 +21,6 @@ import org.bitcoinj.base.internal.ByteUtils;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
@ -50,7 +49,7 @@ public class FeeFilterMessage extends Message {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
feeRate = Coin.ofSat(readInt64());
feeRate = Coin.ofSat(ByteUtils.readInt64(payload));
check(feeRate.signum() >= 0, () -> new ProtocolException("fee rate out of range: " + feeRate));
}

View File

@ -18,6 +18,7 @@
package org.bitcoinj.core;
import org.bitcoinj.base.Sha256Hash;
import org.bitcoinj.base.internal.Buffers;
import java.io.IOException;
import java.io.OutputStream;
@ -67,7 +68,7 @@ public class FilteredBlock extends Message {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
byte[] headerBytes = readBytes(Block.HEADER_SIZE);
byte[] headerBytes = Buffers.readBytes(payload, Block.HEADER_SIZE);
header = params.getDefaultSerializer().makeBlock(ByteBuffer.wrap(headerBytes));
merkleTree = new PartialMerkleTree(params, payload);
}

View File

@ -51,15 +51,15 @@ public class GetBlocksMessage extends Message {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
version = readUint32();
int startCount = readVarInt().intValue();
version = ByteUtils.readUint32(payload);
int startCount = VarInt.read(payload).intValue();
if (startCount > 500)
throw new ProtocolException("Number of locators cannot be > 500, received: " + startCount);
locator = new BlockLocator();
for (int i = 0; i < startCount; i++) {
locator = locator.add(readHash());
locator = locator.add(Sha256Hash.read(payload));
}
stopHash = readHash();
stopHash = Sha256Hash.read(payload);
}
public BlockLocator getLocator() {

View File

@ -69,7 +69,7 @@ public class HeadersMessage extends Message {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
int numHeaders = readVarInt().intValue();
int numHeaders = VarInt.read(payload).intValue();
if (numHeaders > MAX_HEADERS)
throw new ProtocolException("Too many headers: got " + numHeaders + " which is larger than " +
MAX_HEADERS);

View File

@ -18,6 +18,7 @@
package org.bitcoinj.core;
import com.google.common.base.MoreObjects;
import org.bitcoinj.base.Sha256Hash;
import org.bitcoinj.base.VarInt;
import org.bitcoinj.base.internal.ByteUtils;
@ -71,7 +72,7 @@ public abstract class ListMessage extends Message {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
long arrayLen = readVarInt().longValue();
long arrayLen = VarInt.read(payload).longValue();
if (arrayLen > MAX_INVENTORY_ITEMS)
throw new ProtocolException("Too many items in INV message: " + arrayLen);
@ -81,11 +82,11 @@ public abstract class ListMessage extends Message {
if (payload.remaining() < InventoryItem.MESSAGE_LENGTH) {
throw new ProtocolException("Ran off the end of the INV");
}
int typeCode = (int) readUint32();
int typeCode = (int) ByteUtils.readUint32(payload);
InventoryItem.Type type = InventoryItem.Type.ofCode(typeCode);
if (type == null)
throw new ProtocolException("Unknown CInv type: " + typeCode);
InventoryItem item = new InventoryItem(type, readHash());
InventoryItem item = new InventoryItem(type, Sha256Hash.read(payload));
items.add(item);
}
}

View File

@ -18,9 +18,6 @@
package org.bitcoinj.core;
import org.bitcoinj.base.Sha256Hash;
import org.bitcoinj.base.VarInt;
import org.bitcoinj.base.internal.Buffers;
import org.bitcoinj.base.internal.ByteUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -28,7 +25,6 @@ import javax.annotation.Nullable;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
@ -149,51 +145,6 @@ public abstract class Message {
return bitcoinSerialize().length;
}
protected int readInt32() throws BufferUnderflowException {
return ByteUtils.readInt32(payload);
}
protected long readUint32() throws BufferUnderflowException {
return ByteUtils.readUint32(payload);
}
protected long readInt64() throws BufferUnderflowException {
return ByteUtils.readInt64(payload);
}
protected BigInteger readUint64() throws BufferUnderflowException {
// Java does not have an unsigned 64 bit type. So scrape it off the wire then flip.
return new BigInteger(ByteUtils.reverseBytes(readBytes(8)));
}
protected VarInt readVarInt() throws BufferUnderflowException {
return VarInt.read(payload);
}
protected byte[] readBytes(int length) throws BufferUnderflowException {
return Buffers.readBytes(payload, length);
}
protected byte readByte() throws BufferUnderflowException {
return payload.get();
}
protected byte[] readByteArray() throws BufferUnderflowException {
return Buffers.readLengthPrefixedBytes(payload);
}
protected String readStr() throws BufferUnderflowException {
return Buffers.readLengthPrefixedString(payload);
}
protected Sha256Hash readHash() throws BufferUnderflowException {
return Sha256Hash.read(payload);
}
protected void skipBytes(int numBytes) throws BufferUnderflowException {
Buffers.skipBytes(payload, numBytes);
}
/** Network parameters this message was created with. */
public NetworkParameters getParams() {
return params;

View File

@ -20,6 +20,7 @@ package org.bitcoinj.core;
import org.bitcoinj.base.Sha256Hash;
import org.bitcoinj.base.VarInt;
import org.bitcoinj.base.internal.Buffers;
import org.bitcoinj.base.internal.ByteUtils;
import java.io.IOException;
@ -123,15 +124,15 @@ public class PartialMerkleTree extends Message {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
transactionCount = (int)readUint32();
transactionCount = (int) ByteUtils.readUint32(payload);
int nHashes = readVarInt().intValue();
int nHashes = VarInt.read(payload).intValue();
hashes = new ArrayList<>(Math.min(nHashes, Utils.MAX_INITIAL_ARRAY_LENGTH));
for (int i = 0; i < nHashes; i++)
hashes.add(readHash());
hashes.add(Sha256Hash.read(payload));
int nFlagBytes = readVarInt().intValue();
matchedChildBits = readBytes(nFlagBytes);
int nFlagBytes = VarInt.read(payload).intValue();
matchedChildBits = Buffers.readBytes(payload, nFlagBytes);
}
// Based on CPartialMerkleTree::TraverseAndBuild in Bitcoin Core.

View File

@ -19,6 +19,7 @@ package org.bitcoinj.core;
import com.google.common.io.BaseEncoding;
import org.bitcoinj.base.VarInt;
import org.bitcoinj.base.internal.Buffers;
import org.bitcoinj.base.internal.TimeUtils;
import org.bitcoinj.crypto.internal.CryptoUtils;
import org.bitcoinj.base.internal.ByteUtils;
@ -234,14 +235,14 @@ public class PeerAddress extends ChildMessage {
throw new IllegalStateException("invalid protocolVersion: " + protocolVersion);
if (protocolVersion >= 1) {
time = Optional.of(Instant.ofEpochSecond(readUint32()));
time = Optional.of(Instant.ofEpochSecond(ByteUtils.readUint32(payload)));
} else {
time = Optional.empty();
}
if (protocolVersion == 2) {
services = Services.of(VarInt.read(payload).longValue());
int networkId = readByte();
byte[] addrBytes = readByteArray();
int networkId = payload.get();
byte[] addrBytes = Buffers.readLengthPrefixedBytes(payload);
int addrLen = addrBytes.length;
Optional<NetworkId> id = NetworkId.of(networkId);
if (id.isPresent()) {
@ -289,7 +290,7 @@ public class PeerAddress extends ChildMessage {
}
} else {
services = Services.read(payload);
byte[] addrBytes = readBytes(16);
byte[] addrBytes = Buffers.readBytes(payload, 16);
if (Arrays.equals(ONIONCAT_PREFIX, Arrays.copyOf(addrBytes, 6))) {
byte[] onionAddress = Arrays.copyOfRange(addrBytes, 6, 16);
hostname = BASE32.encode(onionAddress) + ".onion";

View File

@ -58,7 +58,7 @@ public class Ping extends Message {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
nonce = readInt64();
nonce = ByteUtils.readInt64(payload);
}
/** @deprecated returns true */

View File

@ -46,7 +46,7 @@ public class Pong extends Message {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
nonce = readInt64();
nonce = ByteUtils.readInt64(payload);
}
@Override

View File

@ -19,6 +19,7 @@ package org.bitcoinj.core;
import org.bitcoinj.base.Sha256Hash;
import org.bitcoinj.base.VarInt;
import org.bitcoinj.base.internal.Buffers;
import java.io.IOException;
import java.io.OutputStream;
@ -96,11 +97,11 @@ public class RejectMessage extends Message {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
message = readStr();
code = RejectCode.fromCode(readByte());
reason = readStr();
message = Buffers.readLengthPrefixedString(payload);
code = RejectCode.fromCode(payload.get());
reason = Buffers.readLengthPrefixedString(payload);
if (message.equals("block") || message.equals("tx"))
messageHash = readHash();
messageHash = Sha256Hash.read(payload);
}
@Override

View File

@ -23,6 +23,7 @@ import org.bitcoinj.base.Address;
import org.bitcoinj.base.Coin;
import org.bitcoinj.base.Sha256Hash;
import org.bitcoinj.base.VarInt;
import org.bitcoinj.base.internal.Buffers;
import org.bitcoinj.base.internal.TimeUtils;
import org.bitcoinj.core.LockTime.HeightLock;
import org.bitcoinj.core.LockTime.TimeLock;
@ -653,13 +654,13 @@ public class Transaction extends ChildMessage {
// version
version = readUint32();
version = ByteUtils.readUint32(payload);
byte flags = 0;
// Try to parse the inputs. In case the dummy is there, this will be read as an empty array list.
parseInputs();
if (inputs.size() == 0 && allowWitness) {
// We read a dummy or an empty input
flags = readByte();
flags = payload.get();
if (flags != 0) {
parseInputs();
@ -687,50 +688,50 @@ public class Transaction extends ChildMessage {
throw new ProtocolException("Unknown transaction optional data");
}
// lock_time
vLockTime = LockTime.of(readUint32());
vLockTime = LockTime.of(ByteUtils.readUint32(payload));
}
private void parseInputs() {
VarInt numInputsVarInt = readVarInt();
VarInt numInputsVarInt = VarInt.read(payload);
int numInputs = numInputsVarInt.intValue();
inputs = new ArrayList<>(Math.min((int) numInputs, Utils.MAX_INITIAL_ARRAY_LENGTH));
for (long i = 0; i < numInputs; i++) {
TransactionInput input = new TransactionInput(params, this, payload.slice(), serializer);
inputs.add(input);
// intentionally read again, due to the slice above
skipBytes(TransactionOutPoint.MESSAGE_LENGTH);
VarInt scriptLenVarInt = readVarInt();
Buffers.skipBytes(payload, TransactionOutPoint.MESSAGE_LENGTH);
VarInt scriptLenVarInt = VarInt.read(payload);
int scriptLen = scriptLenVarInt.intValue();
skipBytes(scriptLen + 4);
Buffers.skipBytes(payload, scriptLen + 4);
}
}
private void parseOutputs() {
VarInt numOutputsVarInt = readVarInt();
VarInt numOutputsVarInt = VarInt.read(payload);
int numOutputs = numOutputsVarInt.intValue();
outputs = new ArrayList<>(Math.min((int) numOutputs, Utils.MAX_INITIAL_ARRAY_LENGTH));
for (long i = 0; i < numOutputs; i++) {
TransactionOutput output = new TransactionOutput(params, this, payload.slice(), serializer);
outputs.add(output);
// intentionally read again, due to the slice above
skipBytes(8); // value
VarInt scriptLenVarInt = readVarInt();
Buffers.skipBytes(payload, 8); // value
VarInt scriptLenVarInt = VarInt.read(payload);
int scriptLen = scriptLenVarInt.intValue();
skipBytes(scriptLen);
Buffers.skipBytes(payload, scriptLen);
}
}
private void parseWitnesses() {
int numWitnesses = inputs.size();
for (int i = 0; i < numWitnesses; i++) {
VarInt pushCountVarInt = readVarInt();
VarInt pushCountVarInt = VarInt.read(payload);
int pushCount = pushCountVarInt.intValue();
TransactionWitness witness = new TransactionWitness(pushCount);
getInput(i).setWitness(witness);
for (int y = 0; y < pushCount; y++) {
VarInt pushSizeVarInt = readVarInt();
VarInt pushSizeVarInt = VarInt.read(payload);
int pushSize = pushSizeVarInt.intValue();
byte[] push = readBytes(pushSize);
byte[] push = Buffers.readBytes(payload, pushSize);
witness.setPush(y, push);
}
}

View File

@ -20,6 +20,7 @@ package org.bitcoinj.core;
import org.bitcoinj.base.Coin;
import org.bitcoinj.base.Sha256Hash;
import org.bitcoinj.base.VarInt;
import org.bitcoinj.base.internal.Buffers;
import org.bitcoinj.base.internal.ByteUtils;
import org.bitcoinj.base.internal.InternalUtils;
import org.bitcoinj.script.Script;
@ -162,9 +163,9 @@ public class TransactionInput extends ChildMessage {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
outpoint = new TransactionOutPoint(params, payload, this, serializer);
int scriptLen = readVarInt().intValue();
scriptBytes = readBytes(scriptLen);
sequence = readUint32();
int scriptLen = VarInt.read(payload).intValue();
scriptBytes = Buffers.readBytes(payload, scriptLen);
sequence = ByteUtils.readUint32(payload);
}
@Override

View File

@ -105,8 +105,8 @@ public class TransactionOutPoint extends ChildMessage {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
hash = readHash();
index = readUint32();
hash = Sha256Hash.read(payload);
index = ByteUtils.readUint32(payload);
}
@Override

View File

@ -22,6 +22,7 @@ import org.bitcoinj.base.Coin;
import org.bitcoinj.base.ScriptType;
import org.bitcoinj.base.Sha256Hash;
import org.bitcoinj.base.VarInt;
import org.bitcoinj.base.internal.Buffers;
import org.bitcoinj.base.internal.ByteUtils;
import org.bitcoinj.crypto.ECKey;
import org.bitcoinj.script.Script;
@ -134,12 +135,12 @@ public class TransactionOutput extends ChildMessage {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
value = readInt64();
value = ByteUtils.readInt64(payload);
// Negative values obviously make no sense, except for -1 which is used as a sentinel value when calculating
// SIGHASH_SINGLE signatures, so unfortunately we have to allow that here.
check(value >= 0 || value == -1, () -> new ProtocolException("value out of range: " + value));
int scriptLen = readVarInt().intValue();
scriptBytes = readBytes(scriptLen);
int scriptLen = VarInt.read(payload).intValue();
scriptBytes = Buffers.readBytes(payload, scriptLen);
}
@Override

View File

@ -18,6 +18,7 @@ package org.bitcoinj.core;
import com.google.common.net.InetAddresses;
import org.bitcoinj.base.VarInt;
import org.bitcoinj.base.internal.Buffers;
import org.bitcoinj.base.internal.TimeUtils;
import org.bitcoinj.base.internal.ByteUtils;
@ -114,9 +115,9 @@ public class VersionMessage extends Message {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
clientVersion = (int) readUint32();
clientVersion = (int) ByteUtils.readUint32(payload);
localServices = Services.read(payload);
time = Instant.ofEpochSecond(readInt64());
time = Instant.ofEpochSecond(ByteUtils.readInt64(payload));
receivingAddr = new PeerAddress(params, payload, this, serializer.withProtocolVersion(0));
if (clientVersion >= 106) {
fromAddr = new PeerAddress(params, payload, this, serializer.withProtocolVersion(0));
@ -124,13 +125,13 @@ public class VersionMessage extends Message {
// We don't care about the localhost nonce. It's used to detect connecting back to yourself in cases where
// there are NATs and proxies in the way. However we don't listen for inbound connections so it's
// irrelevant.
skipBytes(8);
Buffers.skipBytes(payload, 8);
// string subVer (currently "")
subVer = readStr();
subVer = Buffers.readLengthPrefixedString(payload);
// int bestHeight (size of known block chain).
bestHeight = readUint32();
bestHeight = ByteUtils.readUint32(payload);
if (clientVersion >= params.getProtocolVersionNum(NetworkParameters.ProtocolVersion.BLOOM_FILTER)) {
relayTxesBeforeFilter = readByte() != 0;
relayTxesBeforeFilter = payload.get() != 0;
} else {
relayTxesBeforeFilter = true;
}

View File

@ -18,6 +18,7 @@
package org.bitcoinj.core;
import org.bitcoinj.base.VarInt;
import org.bitcoinj.base.internal.Buffers;
import org.bitcoinj.params.TestNet3Params;
import org.junit.Test;
@ -42,7 +43,7 @@ public class MessageTest {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
readStr();
Buffers.readLengthPrefixedString(payload);
}
}
@ -61,7 +62,7 @@ public class MessageTest {
@Override
protected void parse() throws BufferUnderflowException, ProtocolException {
readByteArray();
Buffers.readLengthPrefixedBytes(payload);
}
}
}