3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-13 10:45:51 +00:00

Add support for block headers of variable length, when parsing headers messages.

This commit is contained in:
Ross Nicoll 2015-10-18 12:41:10 +01:00
parent e136642807
commit 1c74aac27e
5 changed files with 37 additions and 20 deletions

View File

@ -266,8 +266,8 @@ public class BitcoinSerializer extends MessageSerializer {
* serialization format support. * serialization format support.
*/ */
@Override @Override
public Block makeBlock(final byte[] payloadBytes, final int length) throws ProtocolException { public Block makeBlock(final byte[] payloadBytes, final int offset, final int length) throws ProtocolException {
return new Block(params, payloadBytes, this, length); return new Block(params, payloadBytes, offset, this, length);
} }
/** /**

View File

@ -134,6 +134,21 @@ public class Block extends Message {
super(params, payloadBytes, 0, serializer, length); super(params, payloadBytes, 0, serializer, length);
} }
/**
* Construct a block object from the Bitcoin wire format.
* @param params NetworkParameters object.
* @param payloadBytes the payload to extract the block from.
* @param offset The location of the first payload byte within the array.
* @param serializer the serializer to use for this message.
* @param length The length of message if known. Usually this is provided when deserializing of the wire
* as the length will be provided as part of the header. If unknown then set to Message.UNKNOWN_LENGTH
* @throws ProtocolException
*/
public Block(NetworkParameters params, byte[] payloadBytes, int offset, MessageSerializer serializer, int length)
throws ProtocolException {
super(params, payloadBytes, offset, serializer, length);
}
/** /**
* Construct a block object from the Bitcoin wire format. Used in the case of a block * Construct a block object from the Bitcoin wire format. Used in the case of a block
* contained within another message (i.e. for AuxPoW header). * contained within another message (i.e. for AuxPoW header).

View File

@ -64,7 +64,7 @@ class DummySerializer extends MessageSerializer {
} }
@Override @Override
public Block makeBlock(byte[] payloadBytes, int length) throws UnsupportedOperationException { public Block makeBlock(byte[] payloadBytes, int offset, int length) throws UnsupportedOperationException {
throw new UnsupportedOperationException(DEFAULT_EXCEPTION_MESSAGE); throw new UnsupportedOperationException(DEFAULT_EXCEPTION_MESSAGE);
} }

View File

@ -64,33 +64,27 @@ public class HeadersMessage extends Message {
@Override @Override
protected void parse() throws ProtocolException { protected void parse() throws ProtocolException {
if (length == UNKNOWN_LENGTH) {
int saveCursor = cursor;
long numHeaders = readVarInt();
cursor = saveCursor;
// Each header has 80 bytes and one more byte for transactions number which is 00.
length = (Block.HEADER_SIZE + 1) * (int)numHeaders;
}
long numHeaders = readVarInt(); long numHeaders = readVarInt();
if (numHeaders > MAX_HEADERS) if (numHeaders > MAX_HEADERS)
throw new ProtocolException("Too many headers: got " + numHeaders + " which is larger than " + throw new ProtocolException("Too many headers: got " + numHeaders + " which is larger than " +
MAX_HEADERS); MAX_HEADERS);
blockHeaders = new ArrayList<Block>(); blockHeaders = new ArrayList<Block>();
final BitcoinSerializer serializer = this.params.getSerializer(true);
for (int i = 0; i < numHeaders; ++i) { for (int i = 0; i < numHeaders; ++i) {
// Read 80 bytes of the header and one more byte for the transaction list, which is always a 00 because the final Block newBlockHeader = serializer.makeBlock(payload, cursor, UNKNOWN_LENGTH);
// transaction list is empty. if (newBlockHeader.hasTransactions()) {
byte[] blockHeader = readBytes(Block.HEADER_SIZE + 1);
if (blockHeader[Block.HEADER_SIZE] != 0)
throw new ProtocolException("Block header does not end with a null byte"); throw new ProtocolException("Block header does not end with a null byte");
Block newBlockHeader = this.params.getSerializer(true) }
.makeBlock(blockHeader, Block.HEADER_SIZE + 1); cursor += newBlockHeader.optimalEncodingMessageSize;
blockHeaders.add(newBlockHeader); blockHeaders.add(newBlockHeader);
} }
if (length == UNKNOWN_LENGTH) {
length = cursor - offset;
}
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
for (int i = 0; i < numHeaders; ++i) { for (int i = 0; i < numHeaders; ++i) {
log.debug(this.blockHeaders.get(i).toString()); log.debug(this.blockHeaders.get(i).toString());

View File

@ -69,7 +69,15 @@ public abstract class MessageSerializer {
* length as block length. * length as block length.
*/ */
public final Block makeBlock(byte[] payloadBytes) throws ProtocolException { public final Block makeBlock(byte[] payloadBytes) throws ProtocolException {
return makeBlock(payloadBytes, payloadBytes.length); return makeBlock(payloadBytes, 0, payloadBytes.length);
}
/**
* Make a block from the payload, using an offset of zero and the provided
* length as block length.
*/
public final Block makeBlock(byte[] payloadBytes, int length) throws ProtocolException {
return makeBlock(payloadBytes, 0, length);
} }
/** /**
@ -77,7 +85,7 @@ public abstract class MessageSerializer {
* length as block length. Extension point for alternative * length as block length. Extension point for alternative
* serialization format support. * serialization format support.
*/ */
public abstract Block makeBlock(byte[] payloadBytes, int length) throws ProtocolException; public abstract Block makeBlock(final byte[] payloadBytes, final int offset, final int length) throws ProtocolException, UnsupportedOperationException;
/** /**
* Make an filter message from the payload. Extension point for alternative * Make an filter message from the payload. Extension point for alternative