mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-02-23 14:40:40 +01:00
Message: extract interface, add BaseMessage
abstract class
This commit is contained in:
parent
78a76f76a5
commit
1fef4e2cdb
17 changed files with 148 additions and 106 deletions
|
@ -26,7 +26,7 @@ import java.util.List;
|
|||
* Abstract superclass for address messages on the P2P network, which contain network addresses of other peers. This is
|
||||
* one of the ways peers can find each other without using the {@link PeerDiscovery} mechanism.
|
||||
*/
|
||||
public abstract class AddressMessage extends Message {
|
||||
public abstract class AddressMessage extends BaseMessage {
|
||||
|
||||
protected static final long MAX_ADDRESSES = 1000;
|
||||
protected List<PeerAddress> addresses;
|
||||
|
|
117
core/src/main/java/org/bitcoinj/core/BaseMessage.java
Normal file
117
core/src/main/java/org/bitcoinj/core/BaseMessage.java
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright by the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.bitcoinj.core;
|
||||
|
||||
import org.bitcoinj.base.Sha256Hash;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.BufferUnderflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* A Message is a data structure that can be serialized/deserialized using the Bitcoin serialization format.
|
||||
* Specific types of messages that are used both in the blockchain, and on the wire, are derived from this
|
||||
* class.
|
||||
* <p>
|
||||
* Instances of this class are not safe for use by multiple threads.
|
||||
*/
|
||||
public abstract class BaseMessage implements Message {
|
||||
private static final Logger log = LoggerFactory.getLogger(BaseMessage.class);
|
||||
|
||||
protected final MessageSerializer serializer;
|
||||
|
||||
protected BaseMessage() {
|
||||
this.serializer = DummySerializer.DEFAULT;
|
||||
}
|
||||
|
||||
protected BaseMessage(MessageSerializer serializer) {
|
||||
this.serializer = serializer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param payload Bitcoin protocol formatted byte array containing message content.
|
||||
* @param serializer the serializer to use for this message.
|
||||
* @throws ProtocolException
|
||||
*/
|
||||
protected BaseMessage(ByteBuffer payload, MessageSerializer serializer) throws ProtocolException {
|
||||
this.serializer = serializer;
|
||||
|
||||
try {
|
||||
parse(payload);
|
||||
} catch(BufferUnderflowException e) {
|
||||
throw new ProtocolException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected BaseMessage(ByteBuffer payload) throws ProtocolException {
|
||||
this(payload, DummySerializer.DEFAULT);
|
||||
}
|
||||
|
||||
// These methods handle the serialization/deserialization using the custom Bitcoin protocol.
|
||||
|
||||
protected abstract void parse(ByteBuffer payload) throws BufferUnderflowException, ProtocolException;
|
||||
|
||||
/**
|
||||
* <p>Serialize this message to a byte array that conforms to the bitcoin wire protocol.</p>
|
||||
*
|
||||
* @return serialized data in Bitcoin protocol format
|
||||
*/
|
||||
@Override
|
||||
public final byte[] bitcoinSerialize() {
|
||||
// No cached array available so serialize parts by stream.
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream(100); // initial size just a guess
|
||||
try {
|
||||
bitcoinSerializeToStream(stream);
|
||||
} catch (IOException e) {
|
||||
// Cannot happen, we are serializing to a memory stream.
|
||||
}
|
||||
return stream.toByteArray();
|
||||
}
|
||||
|
||||
/** @deprecated use {@link #bitcoinSerialize()} */
|
||||
@Deprecated
|
||||
public byte[] unsafeBitcoinSerialize() {
|
||||
return bitcoinSerialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes this message to the provided stream. If you just want the raw bytes use bitcoinSerialize().
|
||||
*/
|
||||
protected void bitcoinSerializeToStream(OutputStream stream) throws IOException {
|
||||
log.error("Error: {} class has not implemented bitcoinSerializeToStream method. Generating message with no payload", getClass());
|
||||
}
|
||||
|
||||
/** @deprecated use {@link Transaction#getTxId()}, {@link Block#getHash()}, {@link FilteredBlock#getHash()} or {@link TransactionOutPoint#hash()} */
|
||||
@Deprecated
|
||||
public Sha256Hash getHash() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size of the serialized message. Note that if the message was deserialized from a payload, this
|
||||
* size can differ from the size of the original payload.
|
||||
* @return size of this object when serialized (in bytes)
|
||||
*/
|
||||
@Override
|
||||
public int getMessageSize() {
|
||||
return bitcoinSerialize().length;
|
||||
}
|
||||
}
|
|
@ -70,7 +70,7 @@ import static org.bitcoinj.base.internal.Preconditions.checkState;
|
|||
*
|
||||
* <p>Instances of this class are not safe for use by multiple threads.</p>
|
||||
*/
|
||||
public class Block extends Message {
|
||||
public class Block extends BaseMessage {
|
||||
/**
|
||||
* Flags used to control which elements of block validation are done on
|
||||
* received blocks.
|
||||
|
|
|
@ -55,7 +55,7 @@ import static org.bitcoinj.base.internal.Preconditions.checkArgument;
|
|||
*
|
||||
* <p>Instances of this class are not safe for use by multiple threads.</p>
|
||||
*/
|
||||
public class BloomFilter extends Message {
|
||||
public class BloomFilter extends BaseMessage {
|
||||
/** The BLOOM_UPDATE_* constants control when the bloom filter is auto-updated by the peer using
|
||||
it as a filter, either never, for all outputs or only for P2PK outputs (default) */
|
||||
public enum BloomUpdate {
|
||||
|
|
|
@ -28,7 +28,7 @@ import java.nio.ByteBuffer;
|
|||
*
|
||||
* <p>Instances of this class are not safe for use by multiple threads.</p>
|
||||
*/
|
||||
public abstract class EmptyMessage extends Message {
|
||||
public abstract class EmptyMessage extends BaseMessage {
|
||||
|
||||
public EmptyMessage() {
|
||||
super();
|
||||
|
|
|
@ -34,7 +34,7 @@ import static org.bitcoinj.base.internal.Preconditions.check;
|
|||
*
|
||||
* <p>Instances of this class are not safe for use by multiple threads.</p>
|
||||
*/
|
||||
public class FeeFilterMessage extends Message {
|
||||
public class FeeFilterMessage extends BaseMessage {
|
||||
private Coin feeRate;
|
||||
|
||||
public FeeFilterMessage(ByteBuffer payload) {
|
||||
|
|
|
@ -37,7 +37,7 @@ import java.util.Objects;
|
|||
*
|
||||
* <p>Instances of this class are not safe for use by multiple threads.</p>
|
||||
*/
|
||||
public class FilteredBlock extends Message {
|
||||
public class FilteredBlock extends BaseMessage {
|
||||
private Block header;
|
||||
|
||||
private PartialMerkleTree merkleTree;
|
||||
|
|
|
@ -34,7 +34,7 @@ import static org.bitcoinj.base.internal.Preconditions.check;
|
|||
*
|
||||
* <p>Instances of this class are not safe for use by multiple threads.</p>
|
||||
*/
|
||||
public class GetBlocksMessage extends Message {
|
||||
public class GetBlocksMessage extends BaseMessage {
|
||||
|
||||
protected long version;
|
||||
protected BlockLocator locator;
|
||||
|
|
|
@ -38,7 +38,7 @@ import static org.bitcoinj.base.internal.Preconditions.check;
|
|||
*
|
||||
* <p>Instances of this class are not safe for use by multiple threads.</p>
|
||||
*/
|
||||
public class HeadersMessage extends Message {
|
||||
public class HeadersMessage extends BaseMessage {
|
||||
private static final Logger log = LoggerFactory.getLogger(HeadersMessage.class);
|
||||
|
||||
// The main client will never send us more than this number of headers.
|
||||
|
|
|
@ -37,7 +37,7 @@ import static org.bitcoinj.base.internal.Preconditions.check;
|
|||
*
|
||||
* <p>Instances of this class are not safe for use by multiple threads.</p>
|
||||
*/
|
||||
public abstract class ListMessage extends Message {
|
||||
public abstract class ListMessage extends BaseMessage {
|
||||
|
||||
// For some reason the compiler complains if this is inside InventoryItem
|
||||
protected List<InventoryItem> items;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
* Copyright 2014 Andreas Schildbach
|
||||
* Copyright by the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -17,102 +16,28 @@
|
|||
|
||||
package org.bitcoinj.core;
|
||||
|
||||
import org.bitcoinj.base.Sha256Hash;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.BufferUnderflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* <p>A Message is a data structure that can be serialized/deserialized using the Bitcoin serialization format.
|
||||
* Specific types of messages that are used both in the block chain, and on the wire, are derived from this
|
||||
* class.</p>
|
||||
*
|
||||
* <p>Instances of this class are not safe for use by multiple threads.</p>
|
||||
* A Message is a data structure that can be serialized/deserialized using the Bitcoin serialization format.
|
||||
* Classes that can be serialized to the blockchain or P2P protocol should implement this interface.
|
||||
*/
|
||||
public abstract class Message {
|
||||
private static final Logger log = LoggerFactory.getLogger(Message.class);
|
||||
|
||||
public static final int MAX_SIZE = 0x02000000; // 32MB
|
||||
|
||||
protected final MessageSerializer serializer;
|
||||
|
||||
protected Message() {
|
||||
this.serializer = DummySerializer.DEFAULT;
|
||||
}
|
||||
|
||||
protected Message(MessageSerializer serializer) {
|
||||
this.serializer = serializer;
|
||||
}
|
||||
|
||||
public interface Message {
|
||||
/**
|
||||
* @param payload Bitcoin protocol formatted byte array containing message content.
|
||||
* @param serializer the serializer to use for this message.
|
||||
* @throws ProtocolException
|
||||
* Maximum size of a Bitcoin P2P Message (32 MB)
|
||||
*/
|
||||
protected Message(ByteBuffer payload, MessageSerializer serializer) throws ProtocolException {
|
||||
this.serializer = serializer;
|
||||
|
||||
try {
|
||||
parse(payload);
|
||||
} catch(BufferUnderflowException e) {
|
||||
throw new ProtocolException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected Message(ByteBuffer payload) throws ProtocolException {
|
||||
this(payload, DummySerializer.DEFAULT);
|
||||
}
|
||||
|
||||
// These methods handle the serialization/deserialization using the custom Bitcoin protocol.
|
||||
|
||||
protected abstract void parse(ByteBuffer payload) throws BufferUnderflowException, ProtocolException;
|
||||
|
||||
/**
|
||||
* <p>Serialize this message to a byte array that conforms to the bitcoin wire protocol.</p>
|
||||
*
|
||||
* @return a byte array
|
||||
*/
|
||||
public final byte[] bitcoinSerialize() {
|
||||
// No cached array available so serialize parts by stream.
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream(100); // initial size just a guess
|
||||
try {
|
||||
bitcoinSerializeToStream(stream);
|
||||
} catch (IOException e) {
|
||||
// Cannot happen, we are serializing to a memory stream.
|
||||
}
|
||||
return stream.toByteArray();
|
||||
}
|
||||
|
||||
/** @deprecated use {@link #bitcoinSerialize()} */
|
||||
@Deprecated
|
||||
public byte[] unsafeBitcoinSerialize() {
|
||||
return bitcoinSerialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes this message to the provided stream. If you just want the raw bytes use bitcoinSerialize().
|
||||
*/
|
||||
protected void bitcoinSerializeToStream(OutputStream stream) throws IOException {
|
||||
log.error("Error: {} class has not implemented bitcoinSerializeToStream method. Generating message with no payload", getClass());
|
||||
}
|
||||
|
||||
/** @deprecated use {@link Transaction#getTxId()}, {@link Block#getHash()}, {@link FilteredBlock#getHash()} or {@link TransactionOutPoint#hash()} */
|
||||
@Deprecated
|
||||
public Sha256Hash getHash() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
int MAX_SIZE = 0x02000000;
|
||||
|
||||
/**
|
||||
* Return the size of the serialized message. Note that if the message was deserialized from a payload, this
|
||||
* size can differ from the size of the original payload.
|
||||
* @return size of the serialized message in bytes
|
||||
*
|
||||
* @return size of this object when serialized (in bytes)
|
||||
*/
|
||||
public int getMessageSize() {
|
||||
return bitcoinSerialize().length;
|
||||
}
|
||||
int getMessageSize();
|
||||
|
||||
/**
|
||||
* Serialize this message to a byte array that conforms to the Bitcoin wire protocol.
|
||||
*
|
||||
* @return serialized data in Bitcoin protocol format
|
||||
*/
|
||||
byte[] bitcoinSerialize();
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ import java.util.Random;
|
|||
*
|
||||
* <p>Instances of this class are not safe for use by multiple threads.</p>
|
||||
*/
|
||||
public class Ping extends Message {
|
||||
public class Ping extends BaseMessage {
|
||||
private long nonce;
|
||||
|
||||
public Ping(ByteBuffer payload) throws ProtocolException {
|
||||
|
|
|
@ -29,7 +29,7 @@ import java.nio.ByteBuffer;
|
|||
*
|
||||
* <p>Instances of this class are not safe for use by multiple threads.</p>
|
||||
*/
|
||||
public class Pong extends Message {
|
||||
public class Pong extends BaseMessage {
|
||||
private long nonce;
|
||||
|
||||
public Pong(ByteBuffer payload) throws ProtocolException {
|
||||
|
|
|
@ -35,7 +35,7 @@ import java.util.stream.Stream;
|
|||
*
|
||||
* <p>Instances of this class are not safe for use by multiple threads.</p>
|
||||
*/
|
||||
public class RejectMessage extends Message {
|
||||
public class RejectMessage extends BaseMessage {
|
||||
|
||||
private String message, reason;
|
||||
public enum RejectCode {
|
||||
|
|
|
@ -92,7 +92,7 @@ import static org.bitcoinj.base.internal.ByteUtils.writeInt64LE;
|
|||
*
|
||||
* <p>Instances of this class are not safe for use by multiple threads.</p>
|
||||
*/
|
||||
public class Transaction extends Message {
|
||||
public class Transaction extends BaseMessage {
|
||||
private static final Comparator<Transaction> SORT_TX_BY_ID = Comparator.comparing(Transaction::getTxId);
|
||||
|
||||
/**
|
||||
|
|
|
@ -48,7 +48,7 @@ import static org.bitcoinj.base.internal.Preconditions.check;
|
|||
*
|
||||
* <p>Instances of this class are not safe for use by multiple threads.</p>
|
||||
*/
|
||||
public class VersionMessage extends Message {
|
||||
public class VersionMessage extends BaseMessage {
|
||||
|
||||
/** The version of this library release, as a string. */
|
||||
public static final String BITCOINJ_VERSION = "0.17-SNAPSHOT";
|
||||
|
|
|
@ -233,7 +233,7 @@ public class BitcoinSerializerTest {
|
|||
public void testSerializeUnknownMessage() throws Exception {
|
||||
MessageSerializer serializer = MAINNET.getDefaultSerializer();
|
||||
|
||||
Message unknownMessage = new Message() {
|
||||
Message unknownMessage = new BaseMessage() {
|
||||
@Override
|
||||
protected void parse(ByteBuffer payload) throws BufferUnderflowException, ProtocolException {
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue