diff --git a/src/main/java/com/limechain/network/Network.java b/src/main/java/com/limechain/network/Network.java index a1e23798f..4f6b7b5e6 100644 --- a/src/main/java/com/limechain/network/Network.java +++ b/src/main/java/com/limechain/network/Network.java @@ -4,6 +4,7 @@ import com.limechain.chain.ChainService; import com.limechain.config.HostConfig; import com.limechain.network.kad.KademliaService; +import com.limechain.network.protocol.sync.SyncService; import com.limechain.network.substream.lightclient.LightMessagesService; import io.ipfs.multihash.Multihash; import io.libp2p.core.Host; @@ -32,6 +33,7 @@ public class Network { private static final int TEN_SECONDS_IN_MS = 10000; private static final int HOST_PORT = 1001; private static Network network; + public SyncService syncService; public LightMessagesService lightMessagesService; public KademliaService kademliaService; private HostBuilder hostBuilder; @@ -51,12 +53,18 @@ private Network(ChainService chainService, HostConfig hostConfig) { hostBuilder = (new HostBuilder()).generateIdentity().listenLocalhost(HOST_PORT); Multihash hostId = Multihash.deserialize(hostBuilder.getPeerId().getBytes()); - kademliaService = new KademliaService("/dot/kad", hostId, isLocalEnabled); + String chainId = chainService.getGenesis().getProtocolId(); + String legacyKadProtocolId = String.format("/%s/kad", chainId); + String syncProtocolId = String.format("/%s/sync/2", chainId); + kademliaService = new KademliaService(legacyKadProtocolId, hostId, isLocalEnabled); lightMessagesService = new LightMessagesService(); + syncService = new SyncService(syncProtocolId); hostBuilder.addProtocols( List.of(new Ping(), kademliaService.getDht(), - lightMessagesService.getLightMessages())); + lightMessagesService.getLightMessages(), + syncService.getSyncMessages() + )); host = hostBuilder.build(); kademliaService.setHost(host); diff --git a/src/main/java/com/limechain/network/kad/KademliaService.java b/src/main/java/com/limechain/network/kad/KademliaService.java index ccbeff5c8..ca4873e35 100644 --- a/src/main/java/com/limechain/network/kad/KademliaService.java +++ b/src/main/java/com/limechain/network/kad/KademliaService.java @@ -51,14 +51,16 @@ private void initialize(String protocolId, Multihash hostId, boolean localEnable * Connects to boot nodes to the Kademlia dht * * @param bootNodes boot nodes set in ChainService + * @return the number of successfully connected nodes */ - public void connectBootNodes(String[] bootNodes) { + public int connectBootNodes(String[] bootNodes) { var bootstrapMultiAddress = List.of(bootNodes).stream() .map(KademliaService::dnsNodeToIp4) .map(MultiAddress::new) .collect(Collectors.toList()); int successfulBootNodes = dht.bootstrapRoutingTable(host, bootstrapMultiAddress, addr -> !addr.contains("wss")); log.log(Level.INFO, "Successfully connected to " + successfulBootNodes + " boot nodes"); + return successfulBootNodes; } /** diff --git a/src/main/java/com/limechain/network/protobuf/SyncMessage.proto b/src/main/java/com/limechain/network/protobuf/SyncMessage.proto new file mode 100644 index 000000000..02df22abd --- /dev/null +++ b/src/main/java/com/limechain/network/protobuf/SyncMessage.proto @@ -0,0 +1,61 @@ +syntax = "proto3"; + +package com.limechain.network.substream.sync.pb; +option java_package = "com.limechain.network.substream.sync.pb"; + +// Schema definition for light client messages. +// Copied from https://github.com/paritytech/substrate/blob/9b08105b8c7106d723c4f470304ad9e2868569d9/client/network/src/schema/api.v1.proto + +// Block enumeration direction. +enum Direction { + // Enumerate in ascending order (from child to parent). + Ascending = 0; + // Enumerate in descending order (from parent to canonical child). + Descending = 1; +} + +// Request block data from a peer. +message BlockRequest { + // Bits of block data to request. + uint32 fields = 1; + // Start from this block. + oneof from_block { + // Start with given hash. + bytes hash = 2; + // Start with given block number. + bytes number = 3; + } + // End at this block. An implementation defined maximum is used when unspecified. + bytes to_block = 4; // optional + // Sequence direction. + Direction direction = 5; + // Maximum number of blocks to return. An implementation defined maximum is used when unspecified. + uint32 max_blocks = 6; // optional +} + +// Response to `BlockRequest` +message BlockResponse { + // Block data for the requested sequence. + repeated BlockData blocks = 1; +} + +// Block data sent in the response. +message BlockData { + // Block header hash. + bytes hash = 1; + // Block header if requested. + bytes header = 2; // optional + // Block body if requested. + repeated bytes body = 3; // optional + // Block receipt if requested. + bytes receipt = 4; // optional + // Block message queue if requested. + bytes message_queue = 5; // optional + // Justification if requested. + bytes justification = 6; // optional + // True if justification should be treated as present but empty. + // This hack is unfortunately necessary because shortcomings in the protobuf format otherwise + // doesn't make in possible to differentiate between a lack of justification and an empty + // justification. + bool is_empty_justification = 7; // optional, false if absent +} diff --git a/src/main/java/com/limechain/network/protocol/sync/SyncController.java b/src/main/java/com/limechain/network/protocol/sync/SyncController.java new file mode 100644 index 000000000..7a159a5d4 --- /dev/null +++ b/src/main/java/com/limechain/network/protocol/sync/SyncController.java @@ -0,0 +1,47 @@ +package com.limechain.network.protocol.sync; + +import com.google.protobuf.ByteString; +import com.limechain.network.substream.sync.pb.SyncMessage; + +import java.util.concurrent.CompletableFuture; + +import static java.util.Objects.isNull; + +public interface SyncController { + CompletableFuture send(SyncMessage.BlockRequest msg); + + /** + * Converts block number to bytes to encode them for the sync message + * @param blockNumber + * @return byte array made from the block number + */ + private static byte[] blockNumberToByteArray(int blockNumber) { + byte byte1 = (byte) (blockNumber); + byte byte2 = (byte) (blockNumber >>> 8); + byte byte3 = (byte) (blockNumber >>> 16); + byte byte4 = (byte) (blockNumber >>> 24); + byte byte5 = (byte) (blockNumber >>> 32); + return new byte[]{byte1, byte2, byte3, byte4, byte5}; + } + + default CompletableFuture sendBlockRequest(int fields, + String fromHash, + Integer fromNumber, + Integer toBlockNumber, + SyncMessage.Direction direction, + int maxBlocks) { + var syncMessage = SyncMessage.BlockRequest.newBuilder() + .setFields(fields) + .setDirection(direction) + .setMaxBlocks(maxBlocks); + if (!isNull(fromHash)) + syncMessage = syncMessage.setHash(ByteString.fromHex(fromHash)); + if (!isNull(fromNumber)) + syncMessage = syncMessage.setNumber(ByteString.copyFrom(blockNumberToByteArray(fromNumber))); + if (!isNull(toBlockNumber)) + syncMessage = syncMessage.setToBlock(ByteString.copyFrom(blockNumberToByteArray(toBlockNumber))); + + var builtSyncMessage = syncMessage.build(); + return send(builtSyncMessage); + } +} diff --git a/src/main/java/com/limechain/network/protocol/sync/SyncMessages.java b/src/main/java/com/limechain/network/protocol/sync/SyncMessages.java new file mode 100644 index 000000000..6f6e4ee0d --- /dev/null +++ b/src/main/java/com/limechain/network/protocol/sync/SyncMessages.java @@ -0,0 +1,46 @@ +package com.limechain.network.protocol.sync; + +import com.limechain.network.substream.sync.pb.SyncMessage; +import io.libp2p.core.AddressBook; +import io.libp2p.core.Host; +import io.libp2p.core.PeerId; +import io.libp2p.core.multiformats.Multiaddr; +import io.libp2p.core.multistream.StrictProtocolBinding; +import lombok.extern.java.Log; + +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; + +@Log +public class SyncMessages extends StrictProtocolBinding { + public SyncMessages(String protocolId, SyncProtocol protocol){ + super(protocolId, protocol); + } + + public SyncMessage.BlockResponse remoteBlockRequest(Host us, AddressBook addrs, PeerId peer, + int fields, + String hash, + Integer number, + Integer toBlock, + SyncMessage.Direction direction, + int maxBlocks){ + SyncController controller = dialPeer(us,peer,addrs); + try{ + SyncMessage.BlockResponse response = controller + .sendBlockRequest(fields, hash, number, toBlock, direction, maxBlocks) + .get(2, TimeUnit.SECONDS); + log.log(Level.INFO, "Received response: " + response.toString()); + return response; + } catch (Exception e){ + log.log(Level.SEVERE, "Error while sending remote call request: ", e); + throw new RuntimeException(e); + } + } + + private SyncController dialPeer(Host us, PeerId peer, AddressBook addrs){ + Multiaddr[] addr = addrs.get(peer).join().toArray(new Multiaddr[0]); + if(addr.length == 0) + throw new IllegalStateException("No addresses known for peer " + peer); + return dial(us, peer, addr).getController().join(); + } +} diff --git a/src/main/java/com/limechain/network/protocol/sync/SyncProtocol.java b/src/main/java/com/limechain/network/protocol/sync/SyncProtocol.java new file mode 100644 index 000000000..ad263f6cd --- /dev/null +++ b/src/main/java/com/limechain/network/protocol/sync/SyncProtocol.java @@ -0,0 +1,70 @@ +package com.limechain.network.protocol.sync; + +import com.limechain.network.substream.sync.pb.SyncMessage; +import io.libp2p.core.ConnectionClosedException; +import io.libp2p.core.Stream; +import io.libp2p.protocol.ProtocolHandler; +import io.libp2p.protocol.ProtocolMessageHandler; +import io.netty.handler.codec.protobuf.ProtobufDecoder; +import io.netty.handler.codec.protobuf.ProtobufEncoder; +import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; +import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender; + +import java.util.concurrent.CompletableFuture; + +public class SyncProtocol extends ProtocolHandler { + public static final int MAX_REQUEST_SIZE = 1024 * 512; + public static final int MAX_RESPONSE_SIZE = 10 * 1024 * 1024; + + public SyncProtocol() { + super(MAX_REQUEST_SIZE, MAX_RESPONSE_SIZE); + } + + @Override + protected CompletableFuture onStartInitiator(Stream stream) { + stream.pushHandler(new ProtobufVarint32FrameDecoder()); + stream.pushHandler(new ProtobufDecoder(SyncMessage.BlockResponse.getDefaultInstance())); + + stream.pushHandler((new ProtobufVarint32LengthFieldPrepender())); + stream.pushHandler((new ProtobufEncoder())); + + Sender handler = new Sender(stream); + stream.pushHandler(handler); + return CompletableFuture.completedFuture(handler); + } + + // Class for handling outgoing requests + static class Sender + implements ProtocolMessageHandler, + SyncController { + private final CompletableFuture resp = new CompletableFuture<>(); + private final Stream stream; + + public Sender(Stream stream) { + this.stream = stream; + } + + @Override + public void onMessage(Stream stream, SyncMessage.BlockResponse msg) { + resp.complete(msg); + stream.closeWrite(); + } + + @Override + public CompletableFuture send(SyncMessage.BlockRequest msg) { + stream.writeAndFlush(msg); + return resp; + } + + @Override + public void onClosed(Stream stream) { + resp.completeExceptionally(new ConnectionClosedException()); + } + + @Override + public void onException(Throwable cause) { + resp.completeExceptionally(cause); + } + + } +} diff --git a/src/main/java/com/limechain/network/protocol/sync/SyncService.java b/src/main/java/com/limechain/network/protocol/sync/SyncService.java new file mode 100644 index 000000000..7a7f2ddaf --- /dev/null +++ b/src/main/java/com/limechain/network/protocol/sync/SyncService.java @@ -0,0 +1,12 @@ +package com.limechain.network.protocol.sync; + +import lombok.Getter; + +@Getter +public class SyncService { + private final SyncMessages syncMessages; + + public SyncService(String protocolId) { + this.syncMessages = new SyncMessages(protocolId, new SyncProtocol()); + } +} diff --git a/src/main/java/com/limechain/network/substream/lightclient/LightMessagesProtocol.java b/src/main/java/com/limechain/network/substream/lightclient/LightMessagesProtocol.java index f0ba121b7..f67ff7e29 100644 --- a/src/main/java/com/limechain/network/substream/lightclient/LightMessagesProtocol.java +++ b/src/main/java/com/limechain/network/substream/lightclient/LightMessagesProtocol.java @@ -101,6 +101,5 @@ public void onClosed(Stream stream) { public void onException(Throwable cause) { resp.completeExceptionally(cause); } - } } diff --git a/src/main/java/com/limechain/network/substream/sync/pb/SyncMessage.java b/src/main/java/com/limechain/network/substream/sync/pb/SyncMessage.java new file mode 100644 index 000000000..455707081 --- /dev/null +++ b/src/main/java/com/limechain/network/substream/sync/pb/SyncMessage.java @@ -0,0 +1,3504 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: SyncMessage.proto + +package com.limechain.network.substream.sync.pb; + +//CHECKSTYLE:OFF +public final class SyncMessage { + private SyncMessage() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistryLite registry) { + } + + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + registerAllExtensions( + (com.google.protobuf.ExtensionRegistryLite) registry); + } + /** + *
+   * Block enumeration direction.
+   * 
+ * + * Protobuf enum {@code com.limechain.network.substream.sync.pb.Direction} + */ + public enum Direction + implements com.google.protobuf.ProtocolMessageEnum { + /** + *
+     * Enumerate in ascending order (from child to parent).
+     * 
+ * + * Ascending = 0; + */ + Ascending(0), + /** + *
+     * Enumerate in descending order (from parent to canonical child).
+     * 
+ * + * Descending = 1; + */ + Descending(1), + UNRECOGNIZED(-1), + ; + + /** + *
+     * Enumerate in ascending order (from child to parent).
+     * 
+ * + * Ascending = 0; + */ + public static final int Ascending_VALUE = 0; + /** + *
+     * Enumerate in descending order (from parent to canonical child).
+     * 
+ * + * Descending = 1; + */ + public static final int Descending_VALUE = 1; + + + public final int getNumber() { + if (this == UNRECOGNIZED) { + throw new java.lang.IllegalArgumentException( + "Can't get the number of an unknown enum value."); + } + return value; + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static Direction valueOf(int value) { + return forNumber(value); + } + + /** + * @param value The numeric wire value of the corresponding enum entry. + * @return The enum associated with the given numeric wire value. + */ + public static Direction forNumber(int value) { + switch (value) { + case 0: return Ascending; + case 1: return Descending; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap + internalGetValueMap() { + return internalValueMap; + } + private static final com.google.protobuf.Internal.EnumLiteMap< + Direction> internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap() { + public Direction findValueByNumber(int number) { + return Direction.forNumber(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + if (this == UNRECOGNIZED) { + throw new java.lang.IllegalStateException( + "Can't get the descriptor of an unrecognized enum value."); + } + return getDescriptor().getValues().get(ordinal()); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return com.limechain.network.substream.sync.pb.SyncMessage.getDescriptor().getEnumTypes().get(0); + } + + private static final Direction[] VALUES = values(); + + public static Direction valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + if (desc.getIndex() == -1) { + return UNRECOGNIZED; + } + return VALUES[desc.getIndex()]; + } + + private final int value; + + private Direction(int value) { + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:com.limechain.network.substream.sync.pb.Direction) + } + + public interface BlockRequestOrBuilder extends + // @@protoc_insertion_point(interface_extends:com.limechain.network.substream.sync.pb.BlockRequest) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * Bits of block data to request.
+     * 
+ * + * uint32 fields = 1; + * @return The fields. + */ + int getFields(); + + /** + *
+     * Start with given hash.
+     * 
+ * + * bytes hash = 2; + * @return Whether the hash field is set. + */ + boolean hasHash(); + /** + *
+     * Start with given hash.
+     * 
+ * + * bytes hash = 2; + * @return The hash. + */ + com.google.protobuf.ByteString getHash(); + + /** + *
+     * Start with given block number.
+     * 
+ * + * bytes number = 3; + * @return Whether the number field is set. + */ + boolean hasNumber(); + /** + *
+     * Start with given block number.
+     * 
+ * + * bytes number = 3; + * @return The number. + */ + com.google.protobuf.ByteString getNumber(); + + /** + *
+     * End at this block. An implementation defined maximum is used when unspecified.
+     * 
+ * + * bytes to_block = 4; + * @return The toBlock. + */ + com.google.protobuf.ByteString getToBlock(); + + /** + *
+     * Sequence direction.
+     * 
+ * + * .com.limechain.network.substream.sync.pb.Direction direction = 5; + * @return The enum numeric value on the wire for direction. + */ + int getDirectionValue(); + /** + *
+     * Sequence direction.
+     * 
+ * + * .com.limechain.network.substream.sync.pb.Direction direction = 5; + * @return The direction. + */ + com.limechain.network.substream.sync.pb.SyncMessage.Direction getDirection(); + + /** + *
+     * Maximum number of blocks to return. An implementation defined maximum is used when unspecified.
+     * 
+ * + * uint32 max_blocks = 6; + * @return The maxBlocks. + */ + int getMaxBlocks(); + + public com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest.FromBlockCase getFromBlockCase(); + } + /** + *
+   * Request block data from a peer.
+   * 
+ * + * Protobuf type {@code com.limechain.network.substream.sync.pb.BlockRequest} + */ + public static final class BlockRequest extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:com.limechain.network.substream.sync.pb.BlockRequest) + BlockRequestOrBuilder { + private static final long serialVersionUID = 0L; + // Use BlockRequest.newBuilder() to construct. + private BlockRequest(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private BlockRequest() { + toBlock_ = com.google.protobuf.ByteString.EMPTY; + direction_ = 0; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new BlockRequest(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.limechain.network.substream.sync.pb.SyncMessage.internal_static_com_limechain_network_substream_sync_pb_BlockRequest_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.limechain.network.substream.sync.pb.SyncMessage.internal_static_com_limechain_network_substream_sync_pb_BlockRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest.class, com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest.Builder.class); + } + + private int fromBlockCase_ = 0; + private java.lang.Object fromBlock_; + public enum FromBlockCase + implements com.google.protobuf.Internal.EnumLite, + com.google.protobuf.AbstractMessage.InternalOneOfEnum { + HASH(2), + NUMBER(3), + FROMBLOCK_NOT_SET(0); + private final int value; + private FromBlockCase(int value) { + this.value = value; + } + /** + * @param value The number of the enum to look for. + * @return The enum associated with the given number. + * @deprecated Use {@link #forNumber(int)} instead. + */ + @java.lang.Deprecated + public static FromBlockCase valueOf(int value) { + return forNumber(value); + } + + public static FromBlockCase forNumber(int value) { + switch (value) { + case 2: return HASH; + case 3: return NUMBER; + case 0: return FROMBLOCK_NOT_SET; + default: return null; + } + } + public int getNumber() { + return this.value; + } + }; + + public FromBlockCase + getFromBlockCase() { + return FromBlockCase.forNumber( + fromBlockCase_); + } + + public static final int FIELDS_FIELD_NUMBER = 1; + private int fields_ = 0; + /** + *
+     * Bits of block data to request.
+     * 
+ * + * uint32 fields = 1; + * @return The fields. + */ + @java.lang.Override + public int getFields() { + return fields_; + } + + public static final int HASH_FIELD_NUMBER = 2; + /** + *
+     * Start with given hash.
+     * 
+ * + * bytes hash = 2; + * @return Whether the hash field is set. + */ + @java.lang.Override + public boolean hasHash() { + return fromBlockCase_ == 2; + } + /** + *
+     * Start with given hash.
+     * 
+ * + * bytes hash = 2; + * @return The hash. + */ + @java.lang.Override + public com.google.protobuf.ByteString getHash() { + if (fromBlockCase_ == 2) { + return (com.google.protobuf.ByteString) fromBlock_; + } + return com.google.protobuf.ByteString.EMPTY; + } + + public static final int NUMBER_FIELD_NUMBER = 3; + /** + *
+     * Start with given block number.
+     * 
+ * + * bytes number = 3; + * @return Whether the number field is set. + */ + @java.lang.Override + public boolean hasNumber() { + return fromBlockCase_ == 3; + } + /** + *
+     * Start with given block number.
+     * 
+ * + * bytes number = 3; + * @return The number. + */ + @java.lang.Override + public com.google.protobuf.ByteString getNumber() { + if (fromBlockCase_ == 3) { + return (com.google.protobuf.ByteString) fromBlock_; + } + return com.google.protobuf.ByteString.EMPTY; + } + + public static final int TO_BLOCK_FIELD_NUMBER = 4; + private com.google.protobuf.ByteString toBlock_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+     * End at this block. An implementation defined maximum is used when unspecified.
+     * 
+ * + * bytes to_block = 4; + * @return The toBlock. + */ + @java.lang.Override + public com.google.protobuf.ByteString getToBlock() { + return toBlock_; + } + + public static final int DIRECTION_FIELD_NUMBER = 5; + private int direction_ = 0; + /** + *
+     * Sequence direction.
+     * 
+ * + * .com.limechain.network.substream.sync.pb.Direction direction = 5; + * @return The enum numeric value on the wire for direction. + */ + @java.lang.Override public int getDirectionValue() { + return direction_; + } + /** + *
+     * Sequence direction.
+     * 
+ * + * .com.limechain.network.substream.sync.pb.Direction direction = 5; + * @return The direction. + */ + @java.lang.Override public com.limechain.network.substream.sync.pb.SyncMessage.Direction getDirection() { + com.limechain.network.substream.sync.pb.SyncMessage.Direction result = com.limechain.network.substream.sync.pb.SyncMessage.Direction.forNumber(direction_); + return result == null ? com.limechain.network.substream.sync.pb.SyncMessage.Direction.UNRECOGNIZED : result; + } + + public static final int MAX_BLOCKS_FIELD_NUMBER = 6; + private int maxBlocks_ = 0; + /** + *
+     * Maximum number of blocks to return. An implementation defined maximum is used when unspecified.
+     * 
+ * + * uint32 max_blocks = 6; + * @return The maxBlocks. + */ + @java.lang.Override + public int getMaxBlocks() { + return maxBlocks_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (fields_ != 0) { + output.writeUInt32(1, fields_); + } + if (fromBlockCase_ == 2) { + output.writeBytes( + 2, (com.google.protobuf.ByteString) fromBlock_); + } + if (fromBlockCase_ == 3) { + output.writeBytes( + 3, (com.google.protobuf.ByteString) fromBlock_); + } + if (!toBlock_.isEmpty()) { + output.writeBytes(4, toBlock_); + } + if (direction_ != com.limechain.network.substream.sync.pb.SyncMessage.Direction.Ascending.getNumber()) { + output.writeEnum(5, direction_); + } + if (maxBlocks_ != 0) { + output.writeUInt32(6, maxBlocks_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (fields_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeUInt32Size(1, fields_); + } + if (fromBlockCase_ == 2) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize( + 2, (com.google.protobuf.ByteString) fromBlock_); + } + if (fromBlockCase_ == 3) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize( + 3, (com.google.protobuf.ByteString) fromBlock_); + } + if (!toBlock_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(4, toBlock_); + } + if (direction_ != com.limechain.network.substream.sync.pb.SyncMessage.Direction.Ascending.getNumber()) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(5, direction_); + } + if (maxBlocks_ != 0) { + size += com.google.protobuf.CodedOutputStream + .computeUInt32Size(6, maxBlocks_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest)) { + return super.equals(obj); + } + com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest other = (com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest) obj; + + if (getFields() + != other.getFields()) return false; + if (!getToBlock() + .equals(other.getToBlock())) return false; + if (direction_ != other.direction_) return false; + if (getMaxBlocks() + != other.getMaxBlocks()) return false; + if (!getFromBlockCase().equals(other.getFromBlockCase())) return false; + switch (fromBlockCase_) { + case 2: + if (!getHash() + .equals(other.getHash())) return false; + break; + case 3: + if (!getNumber() + .equals(other.getNumber())) return false; + break; + case 0: + default: + } + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + FIELDS_FIELD_NUMBER; + hash = (53 * hash) + getFields(); + hash = (37 * hash) + TO_BLOCK_FIELD_NUMBER; + hash = (53 * hash) + getToBlock().hashCode(); + hash = (37 * hash) + DIRECTION_FIELD_NUMBER; + hash = (53 * hash) + direction_; + hash = (37 * hash) + MAX_BLOCKS_FIELD_NUMBER; + hash = (53 * hash) + getMaxBlocks(); + switch (fromBlockCase_) { + case 2: + hash = (37 * hash) + HASH_FIELD_NUMBER; + hash = (53 * hash) + getHash().hashCode(); + break; + case 3: + hash = (37 * hash) + NUMBER_FIELD_NUMBER; + hash = (53 * hash) + getNumber().hashCode(); + break; + case 0: + default: + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Request block data from a peer.
+     * 
+ * + * Protobuf type {@code com.limechain.network.substream.sync.pb.BlockRequest} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:com.limechain.network.substream.sync.pb.BlockRequest) + com.limechain.network.substream.sync.pb.SyncMessage.BlockRequestOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.limechain.network.substream.sync.pb.SyncMessage.internal_static_com_limechain_network_substream_sync_pb_BlockRequest_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.limechain.network.substream.sync.pb.SyncMessage.internal_static_com_limechain_network_substream_sync_pb_BlockRequest_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest.class, com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest.Builder.class); + } + + // Construct using com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + fields_ = 0; + toBlock_ = com.google.protobuf.ByteString.EMPTY; + direction_ = 0; + maxBlocks_ = 0; + fromBlockCase_ = 0; + fromBlock_ = null; + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.limechain.network.substream.sync.pb.SyncMessage.internal_static_com_limechain_network_substream_sync_pb_BlockRequest_descriptor; + } + + @java.lang.Override + public com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest getDefaultInstanceForType() { + return com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest.getDefaultInstance(); + } + + @java.lang.Override + public com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest build() { + com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest buildPartial() { + com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest result = new com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest(this); + if (bitField0_ != 0) { buildPartial0(result); } + buildPartialOneofs(result); + onBuilt(); + return result; + } + + private void buildPartial0(com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest result) { + int from_bitField0_ = bitField0_; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.fields_ = fields_; + } + if (((from_bitField0_ & 0x00000008) != 0)) { + result.toBlock_ = toBlock_; + } + if (((from_bitField0_ & 0x00000010) != 0)) { + result.direction_ = direction_; + } + if (((from_bitField0_ & 0x00000020) != 0)) { + result.maxBlocks_ = maxBlocks_; + } + } + + private void buildPartialOneofs(com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest result) { + result.fromBlockCase_ = fromBlockCase_; + result.fromBlock_ = this.fromBlock_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest) { + return mergeFrom((com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest other) { + if (other == com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest.getDefaultInstance()) return this; + if (other.getFields() != 0) { + setFields(other.getFields()); + } + if (other.getToBlock() != com.google.protobuf.ByteString.EMPTY) { + setToBlock(other.getToBlock()); + } + if (other.direction_ != 0) { + setDirectionValue(other.getDirectionValue()); + } + if (other.getMaxBlocks() != 0) { + setMaxBlocks(other.getMaxBlocks()); + } + switch (other.getFromBlockCase()) { + case HASH: { + setHash(other.getHash()); + break; + } + case NUMBER: { + setNumber(other.getNumber()); + break; + } + case FROMBLOCK_NOT_SET: { + break; + } + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 8: { + fields_ = input.readUInt32(); + bitField0_ |= 0x00000001; + break; + } // case 8 + case 18: { + fromBlock_ = input.readBytes(); + fromBlockCase_ = 2; + break; + } // case 18 + case 26: { + fromBlock_ = input.readBytes(); + fromBlockCase_ = 3; + break; + } // case 26 + case 34: { + toBlock_ = input.readBytes(); + bitField0_ |= 0x00000008; + break; + } // case 34 + case 40: { + direction_ = input.readEnum(); + bitField0_ |= 0x00000010; + break; + } // case 40 + case 48: { + maxBlocks_ = input.readUInt32(); + bitField0_ |= 0x00000020; + break; + } // case 48 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int fromBlockCase_ = 0; + private java.lang.Object fromBlock_; + public FromBlockCase + getFromBlockCase() { + return FromBlockCase.forNumber( + fromBlockCase_); + } + + public Builder clearFromBlock() { + fromBlockCase_ = 0; + fromBlock_ = null; + onChanged(); + return this; + } + + private int bitField0_; + + private int fields_ ; + /** + *
+       * Bits of block data to request.
+       * 
+ * + * uint32 fields = 1; + * @return The fields. + */ + @java.lang.Override + public int getFields() { + return fields_; + } + /** + *
+       * Bits of block data to request.
+       * 
+ * + * uint32 fields = 1; + * @param value The fields to set. + * @return This builder for chaining. + */ + public Builder setFields(int value) { + + fields_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + *
+       * Bits of block data to request.
+       * 
+ * + * uint32 fields = 1; + * @return This builder for chaining. + */ + public Builder clearFields() { + bitField0_ = (bitField0_ & ~0x00000001); + fields_ = 0; + onChanged(); + return this; + } + + /** + *
+       * Start with given hash.
+       * 
+ * + * bytes hash = 2; + * @return Whether the hash field is set. + */ + public boolean hasHash() { + return fromBlockCase_ == 2; + } + /** + *
+       * Start with given hash.
+       * 
+ * + * bytes hash = 2; + * @return The hash. + */ + public com.google.protobuf.ByteString getHash() { + if (fromBlockCase_ == 2) { + return (com.google.protobuf.ByteString) fromBlock_; + } + return com.google.protobuf.ByteString.EMPTY; + } + /** + *
+       * Start with given hash.
+       * 
+ * + * bytes hash = 2; + * @param value The hash to set. + * @return This builder for chaining. + */ + public Builder setHash(com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + fromBlockCase_ = 2; + fromBlock_ = value; + onChanged(); + return this; + } + /** + *
+       * Start with given hash.
+       * 
+ * + * bytes hash = 2; + * @return This builder for chaining. + */ + public Builder clearHash() { + if (fromBlockCase_ == 2) { + fromBlockCase_ = 0; + fromBlock_ = null; + onChanged(); + } + return this; + } + + /** + *
+       * Start with given block number.
+       * 
+ * + * bytes number = 3; + * @return Whether the number field is set. + */ + public boolean hasNumber() { + return fromBlockCase_ == 3; + } + /** + *
+       * Start with given block number.
+       * 
+ * + * bytes number = 3; + * @return The number. + */ + public com.google.protobuf.ByteString getNumber() { + if (fromBlockCase_ == 3) { + return (com.google.protobuf.ByteString) fromBlock_; + } + return com.google.protobuf.ByteString.EMPTY; + } + /** + *
+       * Start with given block number.
+       * 
+ * + * bytes number = 3; + * @param value The number to set. + * @return This builder for chaining. + */ + public Builder setNumber(com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + fromBlockCase_ = 3; + fromBlock_ = value; + onChanged(); + return this; + } + /** + *
+       * Start with given block number.
+       * 
+ * + * bytes number = 3; + * @return This builder for chaining. + */ + public Builder clearNumber() { + if (fromBlockCase_ == 3) { + fromBlockCase_ = 0; + fromBlock_ = null; + onChanged(); + } + return this; + } + + private com.google.protobuf.ByteString toBlock_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * End at this block. An implementation defined maximum is used when unspecified.
+       * 
+ * + * bytes to_block = 4; + * @return The toBlock. + */ + @java.lang.Override + public com.google.protobuf.ByteString getToBlock() { + return toBlock_; + } + /** + *
+       * End at this block. An implementation defined maximum is used when unspecified.
+       * 
+ * + * bytes to_block = 4; + * @param value The toBlock to set. + * @return This builder for chaining. + */ + public Builder setToBlock(com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + toBlock_ = value; + bitField0_ |= 0x00000008; + onChanged(); + return this; + } + /** + *
+       * End at this block. An implementation defined maximum is used when unspecified.
+       * 
+ * + * bytes to_block = 4; + * @return This builder for chaining. + */ + public Builder clearToBlock() { + bitField0_ = (bitField0_ & ~0x00000008); + toBlock_ = getDefaultInstance().getToBlock(); + onChanged(); + return this; + } + + private int direction_ = 0; + /** + *
+       * Sequence direction.
+       * 
+ * + * .com.limechain.network.substream.sync.pb.Direction direction = 5; + * @return The enum numeric value on the wire for direction. + */ + @java.lang.Override public int getDirectionValue() { + return direction_; + } + /** + *
+       * Sequence direction.
+       * 
+ * + * .com.limechain.network.substream.sync.pb.Direction direction = 5; + * @param value The enum numeric value on the wire for direction to set. + * @return This builder for chaining. + */ + public Builder setDirectionValue(int value) { + direction_ = value; + bitField0_ |= 0x00000010; + onChanged(); + return this; + } + /** + *
+       * Sequence direction.
+       * 
+ * + * .com.limechain.network.substream.sync.pb.Direction direction = 5; + * @return The direction. + */ + @java.lang.Override + public com.limechain.network.substream.sync.pb.SyncMessage.Direction getDirection() { + com.limechain.network.substream.sync.pb.SyncMessage.Direction result = com.limechain.network.substream.sync.pb.SyncMessage.Direction.forNumber(direction_); + return result == null ? com.limechain.network.substream.sync.pb.SyncMessage.Direction.UNRECOGNIZED : result; + } + /** + *
+       * Sequence direction.
+       * 
+ * + * .com.limechain.network.substream.sync.pb.Direction direction = 5; + * @param value The direction to set. + * @return This builder for chaining. + */ + public Builder setDirection(com.limechain.network.substream.sync.pb.SyncMessage.Direction value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000010; + direction_ = value.getNumber(); + onChanged(); + return this; + } + /** + *
+       * Sequence direction.
+       * 
+ * + * .com.limechain.network.substream.sync.pb.Direction direction = 5; + * @return This builder for chaining. + */ + public Builder clearDirection() { + bitField0_ = (bitField0_ & ~0x00000010); + direction_ = 0; + onChanged(); + return this; + } + + private int maxBlocks_ ; + /** + *
+       * Maximum number of blocks to return. An implementation defined maximum is used when unspecified.
+       * 
+ * + * uint32 max_blocks = 6; + * @return The maxBlocks. + */ + @java.lang.Override + public int getMaxBlocks() { + return maxBlocks_; + } + /** + *
+       * Maximum number of blocks to return. An implementation defined maximum is used when unspecified.
+       * 
+ * + * uint32 max_blocks = 6; + * @param value The maxBlocks to set. + * @return This builder for chaining. + */ + public Builder setMaxBlocks(int value) { + + maxBlocks_ = value; + bitField0_ |= 0x00000020; + onChanged(); + return this; + } + /** + *
+       * Maximum number of blocks to return. An implementation defined maximum is used when unspecified.
+       * 
+ * + * uint32 max_blocks = 6; + * @return This builder for chaining. + */ + public Builder clearMaxBlocks() { + bitField0_ = (bitField0_ & ~0x00000020); + maxBlocks_ = 0; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:com.limechain.network.substream.sync.pb.BlockRequest) + } + + // @@protoc_insertion_point(class_scope:com.limechain.network.substream.sync.pb.BlockRequest) + private static final com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest(); + } + + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public BlockRequest parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public com.limechain.network.substream.sync.pb.SyncMessage.BlockRequest getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface BlockResponseOrBuilder extends + // @@protoc_insertion_point(interface_extends:com.limechain.network.substream.sync.pb.BlockResponse) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * Block data for the requested sequence.
+     * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + java.util.List + getBlocksList(); + /** + *
+     * Block data for the requested sequence.
+     * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + com.limechain.network.substream.sync.pb.SyncMessage.BlockData getBlocks(int index); + /** + *
+     * Block data for the requested sequence.
+     * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + int getBlocksCount(); + /** + *
+     * Block data for the requested sequence.
+     * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + java.util.List + getBlocksOrBuilderList(); + /** + *
+     * Block data for the requested sequence.
+     * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + com.limechain.network.substream.sync.pb.SyncMessage.BlockDataOrBuilder getBlocksOrBuilder( + int index); + } + /** + *
+   * Response to `BlockRequest`
+   * 
+ * + * Protobuf type {@code com.limechain.network.substream.sync.pb.BlockResponse} + */ + public static final class BlockResponse extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:com.limechain.network.substream.sync.pb.BlockResponse) + BlockResponseOrBuilder { + private static final long serialVersionUID = 0L; + // Use BlockResponse.newBuilder() to construct. + private BlockResponse(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private BlockResponse() { + blocks_ = java.util.Collections.emptyList(); + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new BlockResponse(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.limechain.network.substream.sync.pb.SyncMessage.internal_static_com_limechain_network_substream_sync_pb_BlockResponse_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.limechain.network.substream.sync.pb.SyncMessage.internal_static_com_limechain_network_substream_sync_pb_BlockResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse.class, com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse.Builder.class); + } + + public static final int BLOCKS_FIELD_NUMBER = 1; + @SuppressWarnings("serial") + private java.util.List blocks_; + /** + *
+     * Block data for the requested sequence.
+     * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + @java.lang.Override + public java.util.List getBlocksList() { + return blocks_; + } + /** + *
+     * Block data for the requested sequence.
+     * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + @java.lang.Override + public java.util.List + getBlocksOrBuilderList() { + return blocks_; + } + /** + *
+     * Block data for the requested sequence.
+     * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + @java.lang.Override + public int getBlocksCount() { + return blocks_.size(); + } + /** + *
+     * Block data for the requested sequence.
+     * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + @java.lang.Override + public com.limechain.network.substream.sync.pb.SyncMessage.BlockData getBlocks(int index) { + return blocks_.get(index); + } + /** + *
+     * Block data for the requested sequence.
+     * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + @java.lang.Override + public com.limechain.network.substream.sync.pb.SyncMessage.BlockDataOrBuilder getBlocksOrBuilder( + int index) { + return blocks_.get(index); + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + for (int i = 0; i < blocks_.size(); i++) { + output.writeMessage(1, blocks_.get(i)); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < blocks_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1, blocks_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse)) { + return super.equals(obj); + } + com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse other = (com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse) obj; + + if (!getBlocksList() + .equals(other.getBlocksList())) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + if (getBlocksCount() > 0) { + hash = (37 * hash) + BLOCKS_FIELD_NUMBER; + hash = (53 * hash) + getBlocksList().hashCode(); + } + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Response to `BlockRequest`
+     * 
+ * + * Protobuf type {@code com.limechain.network.substream.sync.pb.BlockResponse} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:com.limechain.network.substream.sync.pb.BlockResponse) + com.limechain.network.substream.sync.pb.SyncMessage.BlockResponseOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.limechain.network.substream.sync.pb.SyncMessage.internal_static_com_limechain_network_substream_sync_pb_BlockResponse_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.limechain.network.substream.sync.pb.SyncMessage.internal_static_com_limechain_network_substream_sync_pb_BlockResponse_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse.class, com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse.Builder.class); + } + + // Construct using com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + if (blocksBuilder_ == null) { + blocks_ = java.util.Collections.emptyList(); + } else { + blocks_ = null; + blocksBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.limechain.network.substream.sync.pb.SyncMessage.internal_static_com_limechain_network_substream_sync_pb_BlockResponse_descriptor; + } + + @java.lang.Override + public com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse getDefaultInstanceForType() { + return com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse.getDefaultInstance(); + } + + @java.lang.Override + public com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse build() { + com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse buildPartial() { + com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse result = new com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse(this); + buildPartialRepeatedFields(result); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartialRepeatedFields(com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse result) { + if (blocksBuilder_ == null) { + if (((bitField0_ & 0x00000001) != 0)) { + blocks_ = java.util.Collections.unmodifiableList(blocks_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.blocks_ = blocks_; + } else { + result.blocks_ = blocksBuilder_.build(); + } + } + + private void buildPartial0(com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse result) { + int from_bitField0_ = bitField0_; + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse) { + return mergeFrom((com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse other) { + if (other == com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse.getDefaultInstance()) return this; + if (blocksBuilder_ == null) { + if (!other.blocks_.isEmpty()) { + if (blocks_.isEmpty()) { + blocks_ = other.blocks_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureBlocksIsMutable(); + blocks_.addAll(other.blocks_); + } + onChanged(); + } + } else { + if (!other.blocks_.isEmpty()) { + if (blocksBuilder_.isEmpty()) { + blocksBuilder_.dispose(); + blocksBuilder_ = null; + blocks_ = other.blocks_; + bitField0_ = (bitField0_ & ~0x00000001); + blocksBuilder_ = + com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ? + getBlocksFieldBuilder() : null; + } else { + blocksBuilder_.addAllMessages(other.blocks_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + com.limechain.network.substream.sync.pb.SyncMessage.BlockData m = + input.readMessage( + com.limechain.network.substream.sync.pb.SyncMessage.BlockData.parser(), + extensionRegistry); + if (blocksBuilder_ == null) { + ensureBlocksIsMutable(); + blocks_.add(m); + } else { + blocksBuilder_.addMessage(m); + } + break; + } // case 10 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private java.util.List blocks_ = + java.util.Collections.emptyList(); + private void ensureBlocksIsMutable() { + if (!((bitField0_ & 0x00000001) != 0)) { + blocks_ = new java.util.ArrayList(blocks_); + bitField0_ |= 0x00000001; + } + } + + private com.google.protobuf.RepeatedFieldBuilderV3< + com.limechain.network.substream.sync.pb.SyncMessage.BlockData, com.limechain.network.substream.sync.pb.SyncMessage.BlockData.Builder, com.limechain.network.substream.sync.pb.SyncMessage.BlockDataOrBuilder> blocksBuilder_; + + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public java.util.List getBlocksList() { + if (blocksBuilder_ == null) { + return java.util.Collections.unmodifiableList(blocks_); + } else { + return blocksBuilder_.getMessageList(); + } + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public int getBlocksCount() { + if (blocksBuilder_ == null) { + return blocks_.size(); + } else { + return blocksBuilder_.getCount(); + } + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public com.limechain.network.substream.sync.pb.SyncMessage.BlockData getBlocks(int index) { + if (blocksBuilder_ == null) { + return blocks_.get(index); + } else { + return blocksBuilder_.getMessage(index); + } + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public Builder setBlocks( + int index, com.limechain.network.substream.sync.pb.SyncMessage.BlockData value) { + if (blocksBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureBlocksIsMutable(); + blocks_.set(index, value); + onChanged(); + } else { + blocksBuilder_.setMessage(index, value); + } + return this; + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public Builder setBlocks( + int index, com.limechain.network.substream.sync.pb.SyncMessage.BlockData.Builder builderForValue) { + if (blocksBuilder_ == null) { + ensureBlocksIsMutable(); + blocks_.set(index, builderForValue.build()); + onChanged(); + } else { + blocksBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public Builder addBlocks(com.limechain.network.substream.sync.pb.SyncMessage.BlockData value) { + if (blocksBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureBlocksIsMutable(); + blocks_.add(value); + onChanged(); + } else { + blocksBuilder_.addMessage(value); + } + return this; + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public Builder addBlocks( + int index, com.limechain.network.substream.sync.pb.SyncMessage.BlockData value) { + if (blocksBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureBlocksIsMutable(); + blocks_.add(index, value); + onChanged(); + } else { + blocksBuilder_.addMessage(index, value); + } + return this; + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public Builder addBlocks( + com.limechain.network.substream.sync.pb.SyncMessage.BlockData.Builder builderForValue) { + if (blocksBuilder_ == null) { + ensureBlocksIsMutable(); + blocks_.add(builderForValue.build()); + onChanged(); + } else { + blocksBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public Builder addBlocks( + int index, com.limechain.network.substream.sync.pb.SyncMessage.BlockData.Builder builderForValue) { + if (blocksBuilder_ == null) { + ensureBlocksIsMutable(); + blocks_.add(index, builderForValue.build()); + onChanged(); + } else { + blocksBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public Builder addAllBlocks( + java.lang.Iterable values) { + if (blocksBuilder_ == null) { + ensureBlocksIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, blocks_); + onChanged(); + } else { + blocksBuilder_.addAllMessages(values); + } + return this; + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public Builder clearBlocks() { + if (blocksBuilder_ == null) { + blocks_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + } else { + blocksBuilder_.clear(); + } + return this; + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public Builder removeBlocks(int index) { + if (blocksBuilder_ == null) { + ensureBlocksIsMutable(); + blocks_.remove(index); + onChanged(); + } else { + blocksBuilder_.remove(index); + } + return this; + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public com.limechain.network.substream.sync.pb.SyncMessage.BlockData.Builder getBlocksBuilder( + int index) { + return getBlocksFieldBuilder().getBuilder(index); + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public com.limechain.network.substream.sync.pb.SyncMessage.BlockDataOrBuilder getBlocksOrBuilder( + int index) { + if (blocksBuilder_ == null) { + return blocks_.get(index); } else { + return blocksBuilder_.getMessageOrBuilder(index); + } + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public java.util.List + getBlocksOrBuilderList() { + if (blocksBuilder_ != null) { + return blocksBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(blocks_); + } + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public com.limechain.network.substream.sync.pb.SyncMessage.BlockData.Builder addBlocksBuilder() { + return getBlocksFieldBuilder().addBuilder( + com.limechain.network.substream.sync.pb.SyncMessage.BlockData.getDefaultInstance()); + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public com.limechain.network.substream.sync.pb.SyncMessage.BlockData.Builder addBlocksBuilder( + int index) { + return getBlocksFieldBuilder().addBuilder( + index, com.limechain.network.substream.sync.pb.SyncMessage.BlockData.getDefaultInstance()); + } + /** + *
+       * Block data for the requested sequence.
+       * 
+ * + * repeated .com.limechain.network.substream.sync.pb.BlockData blocks = 1; + */ + public java.util.List + getBlocksBuilderList() { + return getBlocksFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilderV3< + com.limechain.network.substream.sync.pb.SyncMessage.BlockData, com.limechain.network.substream.sync.pb.SyncMessage.BlockData.Builder, com.limechain.network.substream.sync.pb.SyncMessage.BlockDataOrBuilder> + getBlocksFieldBuilder() { + if (blocksBuilder_ == null) { + blocksBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3< + com.limechain.network.substream.sync.pb.SyncMessage.BlockData, com.limechain.network.substream.sync.pb.SyncMessage.BlockData.Builder, com.limechain.network.substream.sync.pb.SyncMessage.BlockDataOrBuilder>( + blocks_, + ((bitField0_ & 0x00000001) != 0), + getParentForChildren(), + isClean()); + blocks_ = null; + } + return blocksBuilder_; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:com.limechain.network.substream.sync.pb.BlockResponse) + } + + // @@protoc_insertion_point(class_scope:com.limechain.network.substream.sync.pb.BlockResponse) + private static final com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse(); + } + + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public BlockResponse parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public com.limechain.network.substream.sync.pb.SyncMessage.BlockResponse getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + public interface BlockDataOrBuilder extends + // @@protoc_insertion_point(interface_extends:com.limechain.network.substream.sync.pb.BlockData) + com.google.protobuf.MessageOrBuilder { + + /** + *
+     * Block header hash.
+     * 
+ * + * bytes hash = 1; + * @return The hash. + */ + com.google.protobuf.ByteString getHash(); + + /** + *
+     * Block header if requested.
+     * 
+ * + * bytes header = 2; + * @return The header. + */ + com.google.protobuf.ByteString getHeader(); + + /** + *
+     * Block body if requested.
+     * 
+ * + * repeated bytes body = 3; + * @return A list containing the body. + */ + java.util.List getBodyList(); + /** + *
+     * Block body if requested.
+     * 
+ * + * repeated bytes body = 3; + * @return The count of body. + */ + int getBodyCount(); + /** + *
+     * Block body if requested.
+     * 
+ * + * repeated bytes body = 3; + * @param index The index of the element to return. + * @return The body at the given index. + */ + com.google.protobuf.ByteString getBody(int index); + + /** + *
+     * Block receipt if requested.
+     * 
+ * + * bytes receipt = 4; + * @return The receipt. + */ + com.google.protobuf.ByteString getReceipt(); + + /** + *
+     * Block message queue if requested.
+     * 
+ * + * bytes message_queue = 5; + * @return The messageQueue. + */ + com.google.protobuf.ByteString getMessageQueue(); + + /** + *
+     * Justification if requested.
+     * 
+ * + * bytes justification = 6; + * @return The justification. + */ + com.google.protobuf.ByteString getJustification(); + + /** + *
+     * True if justification should be treated as present but empty.
+     * This hack is unfortunately necessary because shortcomings in the protobuf format otherwise
+     * doesn't make in possible to differentiate between a lack of justification and an empty
+     * justification.
+     * 
+ * + * bool is_empty_justification = 7; + * @return The isEmptyJustification. + */ + boolean getIsEmptyJustification(); + } + /** + *
+   * Block data sent in the response.
+   * 
+ * + * Protobuf type {@code com.limechain.network.substream.sync.pb.BlockData} + */ + public static final class BlockData extends + com.google.protobuf.GeneratedMessageV3 implements + // @@protoc_insertion_point(message_implements:com.limechain.network.substream.sync.pb.BlockData) + BlockDataOrBuilder { + private static final long serialVersionUID = 0L; + // Use BlockData.newBuilder() to construct. + private BlockData(com.google.protobuf.GeneratedMessageV3.Builder builder) { + super(builder); + } + private BlockData() { + hash_ = com.google.protobuf.ByteString.EMPTY; + header_ = com.google.protobuf.ByteString.EMPTY; + body_ = java.util.Collections.emptyList(); + receipt_ = com.google.protobuf.ByteString.EMPTY; + messageQueue_ = com.google.protobuf.ByteString.EMPTY; + justification_ = com.google.protobuf.ByteString.EMPTY; + } + + @java.lang.Override + @SuppressWarnings({"unused"}) + protected java.lang.Object newInstance( + UnusedPrivateParameter unused) { + return new BlockData(); + } + + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.limechain.network.substream.sync.pb.SyncMessage.internal_static_com_limechain_network_substream_sync_pb_BlockData_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.limechain.network.substream.sync.pb.SyncMessage.internal_static_com_limechain_network_substream_sync_pb_BlockData_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.limechain.network.substream.sync.pb.SyncMessage.BlockData.class, com.limechain.network.substream.sync.pb.SyncMessage.BlockData.Builder.class); + } + + public static final int HASH_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString hash_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+     * Block header hash.
+     * 
+ * + * bytes hash = 1; + * @return The hash. + */ + @java.lang.Override + public com.google.protobuf.ByteString getHash() { + return hash_; + } + + public static final int HEADER_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString header_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+     * Block header if requested.
+     * 
+ * + * bytes header = 2; + * @return The header. + */ + @java.lang.Override + public com.google.protobuf.ByteString getHeader() { + return header_; + } + + public static final int BODY_FIELD_NUMBER = 3; + @SuppressWarnings("serial") + private java.util.List body_; + /** + *
+     * Block body if requested.
+     * 
+ * + * repeated bytes body = 3; + * @return A list containing the body. + */ + @java.lang.Override + public java.util.List + getBodyList() { + return body_; + } + /** + *
+     * Block body if requested.
+     * 
+ * + * repeated bytes body = 3; + * @return The count of body. + */ + public int getBodyCount() { + return body_.size(); + } + /** + *
+     * Block body if requested.
+     * 
+ * + * repeated bytes body = 3; + * @param index The index of the element to return. + * @return The body at the given index. + */ + public com.google.protobuf.ByteString getBody(int index) { + return body_.get(index); + } + + public static final int RECEIPT_FIELD_NUMBER = 4; + private com.google.protobuf.ByteString receipt_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+     * Block receipt if requested.
+     * 
+ * + * bytes receipt = 4; + * @return The receipt. + */ + @java.lang.Override + public com.google.protobuf.ByteString getReceipt() { + return receipt_; + } + + public static final int MESSAGE_QUEUE_FIELD_NUMBER = 5; + private com.google.protobuf.ByteString messageQueue_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+     * Block message queue if requested.
+     * 
+ * + * bytes message_queue = 5; + * @return The messageQueue. + */ + @java.lang.Override + public com.google.protobuf.ByteString getMessageQueue() { + return messageQueue_; + } + + public static final int JUSTIFICATION_FIELD_NUMBER = 6; + private com.google.protobuf.ByteString justification_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+     * Justification if requested.
+     * 
+ * + * bytes justification = 6; + * @return The justification. + */ + @java.lang.Override + public com.google.protobuf.ByteString getJustification() { + return justification_; + } + + public static final int IS_EMPTY_JUSTIFICATION_FIELD_NUMBER = 7; + private boolean isEmptyJustification_ = false; + /** + *
+     * True if justification should be treated as present but empty.
+     * This hack is unfortunately necessary because shortcomings in the protobuf format otherwise
+     * doesn't make in possible to differentiate between a lack of justification and an empty
+     * justification.
+     * 
+ * + * bool is_empty_justification = 7; + * @return The isEmptyJustification. + */ + @java.lang.Override + public boolean getIsEmptyJustification() { + return isEmptyJustification_; + } + + private byte memoizedIsInitialized = -1; + @java.lang.Override + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + memoizedIsInitialized = 1; + return true; + } + + @java.lang.Override + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + if (!hash_.isEmpty()) { + output.writeBytes(1, hash_); + } + if (!header_.isEmpty()) { + output.writeBytes(2, header_); + } + for (int i = 0; i < body_.size(); i++) { + output.writeBytes(3, body_.get(i)); + } + if (!receipt_.isEmpty()) { + output.writeBytes(4, receipt_); + } + if (!messageQueue_.isEmpty()) { + output.writeBytes(5, messageQueue_); + } + if (!justification_.isEmpty()) { + output.writeBytes(6, justification_); + } + if (isEmptyJustification_ != false) { + output.writeBool(7, isEmptyJustification_); + } + getUnknownFields().writeTo(output); + } + + @java.lang.Override + public int getSerializedSize() { + int size = memoizedSize; + if (size != -1) return size; + + size = 0; + if (!hash_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, hash_); + } + if (!header_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, header_); + } + { + int dataSize = 0; + for (int i = 0; i < body_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(body_.get(i)); + } + size += dataSize; + size += 1 * getBodyList().size(); + } + if (!receipt_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(4, receipt_); + } + if (!messageQueue_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(5, messageQueue_); + } + if (!justification_.isEmpty()) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(6, justification_); + } + if (isEmptyJustification_ != false) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(7, isEmptyJustification_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSize = size; + return size; + } + + @java.lang.Override + public boolean equals(final java.lang.Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof com.limechain.network.substream.sync.pb.SyncMessage.BlockData)) { + return super.equals(obj); + } + com.limechain.network.substream.sync.pb.SyncMessage.BlockData other = (com.limechain.network.substream.sync.pb.SyncMessage.BlockData) obj; + + if (!getHash() + .equals(other.getHash())) return false; + if (!getHeader() + .equals(other.getHeader())) return false; + if (!getBodyList() + .equals(other.getBodyList())) return false; + if (!getReceipt() + .equals(other.getReceipt())) return false; + if (!getMessageQueue() + .equals(other.getMessageQueue())) return false; + if (!getJustification() + .equals(other.getJustification())) return false; + if (getIsEmptyJustification() + != other.getIsEmptyJustification()) return false; + if (!getUnknownFields().equals(other.getUnknownFields())) return false; + return true; + } + + @java.lang.Override + public int hashCode() { + if (memoizedHashCode != 0) { + return memoizedHashCode; + } + int hash = 41; + hash = (19 * hash) + getDescriptor().hashCode(); + hash = (37 * hash) + HASH_FIELD_NUMBER; + hash = (53 * hash) + getHash().hashCode(); + hash = (37 * hash) + HEADER_FIELD_NUMBER; + hash = (53 * hash) + getHeader().hashCode(); + if (getBodyCount() > 0) { + hash = (37 * hash) + BODY_FIELD_NUMBER; + hash = (53 * hash) + getBodyList().hashCode(); + } + hash = (37 * hash) + RECEIPT_FIELD_NUMBER; + hash = (53 * hash) + getReceipt().hashCode(); + hash = (37 * hash) + MESSAGE_QUEUE_FIELD_NUMBER; + hash = (53 * hash) + getMessageQueue().hashCode(); + hash = (37 * hash) + JUSTIFICATION_FIELD_NUMBER; + hash = (53 * hash) + getJustification().hashCode(); + hash = (37 * hash) + IS_EMPTY_JUSTIFICATION_FIELD_NUMBER; + hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean( + getIsEmptyJustification()); + hash = (29 * hash) + getUnknownFields().hashCode(); + memoizedHashCode = hash; + return hash; + } + + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockData parseFrom( + java.nio.ByteBuffer data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockData parseFrom( + java.nio.ByteBuffer data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockData parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockData parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockData parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockData parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockData parseFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockData parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockData parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockData parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseDelimitedWithIOException(PARSER, input, extensionRegistry); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockData parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input); + } + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockData parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return com.google.protobuf.GeneratedMessageV3 + .parseWithIOException(PARSER, input, extensionRegistry); + } + + @java.lang.Override + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder() { + return DEFAULT_INSTANCE.toBuilder(); + } + public static Builder newBuilder(com.limechain.network.substream.sync.pb.SyncMessage.BlockData prototype) { + return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype); + } + @java.lang.Override + public Builder toBuilder() { + return this == DEFAULT_INSTANCE + ? new Builder() : new Builder().mergeFrom(this); + } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + *
+     * Block data sent in the response.
+     * 
+ * + * Protobuf type {@code com.limechain.network.substream.sync.pb.BlockData} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessageV3.Builder implements + // @@protoc_insertion_point(builder_implements:com.limechain.network.substream.sync.pb.BlockData) + com.limechain.network.substream.sync.pb.SyncMessage.BlockDataOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.limechain.network.substream.sync.pb.SyncMessage.internal_static_com_limechain_network_substream_sync_pb_BlockData_descriptor; + } + + @java.lang.Override + protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.limechain.network.substream.sync.pb.SyncMessage.internal_static_com_limechain_network_substream_sync_pb_BlockData_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.limechain.network.substream.sync.pb.SyncMessage.BlockData.class, com.limechain.network.substream.sync.pb.SyncMessage.BlockData.Builder.class); + } + + // Construct using com.limechain.network.substream.sync.pb.SyncMessage.BlockData.newBuilder() + private Builder() { + + } + + private Builder( + com.google.protobuf.GeneratedMessageV3.BuilderParent parent) { + super(parent); + + } + @java.lang.Override + public Builder clear() { + super.clear(); + bitField0_ = 0; + hash_ = com.google.protobuf.ByteString.EMPTY; + header_ = com.google.protobuf.ByteString.EMPTY; + body_ = java.util.Collections.emptyList(); + receipt_ = com.google.protobuf.ByteString.EMPTY; + messageQueue_ = com.google.protobuf.ByteString.EMPTY; + justification_ = com.google.protobuf.ByteString.EMPTY; + isEmptyJustification_ = false; + return this; + } + + @java.lang.Override + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.limechain.network.substream.sync.pb.SyncMessage.internal_static_com_limechain_network_substream_sync_pb_BlockData_descriptor; + } + + @java.lang.Override + public com.limechain.network.substream.sync.pb.SyncMessage.BlockData getDefaultInstanceForType() { + return com.limechain.network.substream.sync.pb.SyncMessage.BlockData.getDefaultInstance(); + } + + @java.lang.Override + public com.limechain.network.substream.sync.pb.SyncMessage.BlockData build() { + com.limechain.network.substream.sync.pb.SyncMessage.BlockData result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + @java.lang.Override + public com.limechain.network.substream.sync.pb.SyncMessage.BlockData buildPartial() { + com.limechain.network.substream.sync.pb.SyncMessage.BlockData result = new com.limechain.network.substream.sync.pb.SyncMessage.BlockData(this); + buildPartialRepeatedFields(result); + if (bitField0_ != 0) { buildPartial0(result); } + onBuilt(); + return result; + } + + private void buildPartialRepeatedFields(com.limechain.network.substream.sync.pb.SyncMessage.BlockData result) { + if (((bitField0_ & 0x00000004) != 0)) { + body_ = java.util.Collections.unmodifiableList(body_); + bitField0_ = (bitField0_ & ~0x00000004); + } + result.body_ = body_; + } + + private void buildPartial0(com.limechain.network.substream.sync.pb.SyncMessage.BlockData result) { + int from_bitField0_ = bitField0_; + if (((from_bitField0_ & 0x00000001) != 0)) { + result.hash_ = hash_; + } + if (((from_bitField0_ & 0x00000002) != 0)) { + result.header_ = header_; + } + if (((from_bitField0_ & 0x00000008) != 0)) { + result.receipt_ = receipt_; + } + if (((from_bitField0_ & 0x00000010) != 0)) { + result.messageQueue_ = messageQueue_; + } + if (((from_bitField0_ & 0x00000020) != 0)) { + result.justification_ = justification_; + } + if (((from_bitField0_ & 0x00000040) != 0)) { + result.isEmptyJustification_ = isEmptyJustification_; + } + } + + @java.lang.Override + public Builder clone() { + return super.clone(); + } + @java.lang.Override + public Builder setField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.setField(field, value); + } + @java.lang.Override + public Builder clearField( + com.google.protobuf.Descriptors.FieldDescriptor field) { + return super.clearField(field); + } + @java.lang.Override + public Builder clearOneof( + com.google.protobuf.Descriptors.OneofDescriptor oneof) { + return super.clearOneof(oneof); + } + @java.lang.Override + public Builder setRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + int index, java.lang.Object value) { + return super.setRepeatedField(field, index, value); + } + @java.lang.Override + public Builder addRepeatedField( + com.google.protobuf.Descriptors.FieldDescriptor field, + java.lang.Object value) { + return super.addRepeatedField(field, value); + } + @java.lang.Override + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.limechain.network.substream.sync.pb.SyncMessage.BlockData) { + return mergeFrom((com.limechain.network.substream.sync.pb.SyncMessage.BlockData)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.limechain.network.substream.sync.pb.SyncMessage.BlockData other) { + if (other == com.limechain.network.substream.sync.pb.SyncMessage.BlockData.getDefaultInstance()) return this; + if (other.getHash() != com.google.protobuf.ByteString.EMPTY) { + setHash(other.getHash()); + } + if (other.getHeader() != com.google.protobuf.ByteString.EMPTY) { + setHeader(other.getHeader()); + } + if (!other.body_.isEmpty()) { + if (body_.isEmpty()) { + body_ = other.body_; + bitField0_ = (bitField0_ & ~0x00000004); + } else { + ensureBodyIsMutable(); + body_.addAll(other.body_); + } + onChanged(); + } + if (other.getReceipt() != com.google.protobuf.ByteString.EMPTY) { + setReceipt(other.getReceipt()); + } + if (other.getMessageQueue() != com.google.protobuf.ByteString.EMPTY) { + setMessageQueue(other.getMessageQueue()); + } + if (other.getJustification() != com.google.protobuf.ByteString.EMPTY) { + setJustification(other.getJustification()); + } + if (other.getIsEmptyJustification() != false) { + setIsEmptyJustification(other.getIsEmptyJustification()); + } + this.mergeUnknownFields(other.getUnknownFields()); + onChanged(); + return this; + } + + @java.lang.Override + public final boolean isInitialized() { + return true; + } + + @java.lang.Override + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + if (extensionRegistry == null) { + throw new java.lang.NullPointerException(); + } + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + case 10: { + hash_ = input.readBytes(); + bitField0_ |= 0x00000001; + break; + } // case 10 + case 18: { + header_ = input.readBytes(); + bitField0_ |= 0x00000002; + break; + } // case 18 + case 26: { + com.google.protobuf.ByteString v = input.readBytes(); + ensureBodyIsMutable(); + body_.add(v); + break; + } // case 26 + case 34: { + receipt_ = input.readBytes(); + bitField0_ |= 0x00000008; + break; + } // case 34 + case 42: { + messageQueue_ = input.readBytes(); + bitField0_ |= 0x00000010; + break; + } // case 42 + case 50: { + justification_ = input.readBytes(); + bitField0_ |= 0x00000020; + break; + } // case 50 + case 56: { + isEmptyJustification_ = input.readBool(); + bitField0_ |= 0x00000040; + break; + } // case 56 + default: { + if (!super.parseUnknownField(input, extensionRegistry, tag)) { + done = true; // was an endgroup tag + } + break; + } // default: + } // switch (tag) + } // while (!done) + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.unwrapIOException(); + } finally { + onChanged(); + } // finally + return this; + } + private int bitField0_; + + private com.google.protobuf.ByteString hash_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * Block header hash.
+       * 
+ * + * bytes hash = 1; + * @return The hash. + */ + @java.lang.Override + public com.google.protobuf.ByteString getHash() { + return hash_; + } + /** + *
+       * Block header hash.
+       * 
+ * + * bytes hash = 1; + * @param value The hash to set. + * @return This builder for chaining. + */ + public Builder setHash(com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + hash_ = value; + bitField0_ |= 0x00000001; + onChanged(); + return this; + } + /** + *
+       * Block header hash.
+       * 
+ * + * bytes hash = 1; + * @return This builder for chaining. + */ + public Builder clearHash() { + bitField0_ = (bitField0_ & ~0x00000001); + hash_ = getDefaultInstance().getHash(); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString header_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * Block header if requested.
+       * 
+ * + * bytes header = 2; + * @return The header. + */ + @java.lang.Override + public com.google.protobuf.ByteString getHeader() { + return header_; + } + /** + *
+       * Block header if requested.
+       * 
+ * + * bytes header = 2; + * @param value The header to set. + * @return This builder for chaining. + */ + public Builder setHeader(com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + header_ = value; + bitField0_ |= 0x00000002; + onChanged(); + return this; + } + /** + *
+       * Block header if requested.
+       * 
+ * + * bytes header = 2; + * @return This builder for chaining. + */ + public Builder clearHeader() { + bitField0_ = (bitField0_ & ~0x00000002); + header_ = getDefaultInstance().getHeader(); + onChanged(); + return this; + } + + private java.util.List body_ = java.util.Collections.emptyList(); + private void ensureBodyIsMutable() { + if (!((bitField0_ & 0x00000004) != 0)) { + body_ = new java.util.ArrayList(body_); + bitField0_ |= 0x00000004; + } + } + /** + *
+       * Block body if requested.
+       * 
+ * + * repeated bytes body = 3; + * @return A list containing the body. + */ + public java.util.List + getBodyList() { + return ((bitField0_ & 0x00000004) != 0) ? + java.util.Collections.unmodifiableList(body_) : body_; + } + /** + *
+       * Block body if requested.
+       * 
+ * + * repeated bytes body = 3; + * @return The count of body. + */ + public int getBodyCount() { + return body_.size(); + } + /** + *
+       * Block body if requested.
+       * 
+ * + * repeated bytes body = 3; + * @param index The index of the element to return. + * @return The body at the given index. + */ + public com.google.protobuf.ByteString getBody(int index) { + return body_.get(index); + } + /** + *
+       * Block body if requested.
+       * 
+ * + * repeated bytes body = 3; + * @param index The index to set the value at. + * @param value The body to set. + * @return This builder for chaining. + */ + public Builder setBody( + int index, com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + ensureBodyIsMutable(); + body_.set(index, value); + onChanged(); + return this; + } + /** + *
+       * Block body if requested.
+       * 
+ * + * repeated bytes body = 3; + * @param value The body to add. + * @return This builder for chaining. + */ + public Builder addBody(com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + ensureBodyIsMutable(); + body_.add(value); + onChanged(); + return this; + } + /** + *
+       * Block body if requested.
+       * 
+ * + * repeated bytes body = 3; + * @param values The body to add. + * @return This builder for chaining. + */ + public Builder addAllBody( + java.lang.Iterable values) { + ensureBodyIsMutable(); + com.google.protobuf.AbstractMessageLite.Builder.addAll( + values, body_); + onChanged(); + return this; + } + /** + *
+       * Block body if requested.
+       * 
+ * + * repeated bytes body = 3; + * @return This builder for chaining. + */ + public Builder clearBody() { + body_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000004); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString receipt_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * Block receipt if requested.
+       * 
+ * + * bytes receipt = 4; + * @return The receipt. + */ + @java.lang.Override + public com.google.protobuf.ByteString getReceipt() { + return receipt_; + } + /** + *
+       * Block receipt if requested.
+       * 
+ * + * bytes receipt = 4; + * @param value The receipt to set. + * @return This builder for chaining. + */ + public Builder setReceipt(com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + receipt_ = value; + bitField0_ |= 0x00000008; + onChanged(); + return this; + } + /** + *
+       * Block receipt if requested.
+       * 
+ * + * bytes receipt = 4; + * @return This builder for chaining. + */ + public Builder clearReceipt() { + bitField0_ = (bitField0_ & ~0x00000008); + receipt_ = getDefaultInstance().getReceipt(); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString messageQueue_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * Block message queue if requested.
+       * 
+ * + * bytes message_queue = 5; + * @return The messageQueue. + */ + @java.lang.Override + public com.google.protobuf.ByteString getMessageQueue() { + return messageQueue_; + } + /** + *
+       * Block message queue if requested.
+       * 
+ * + * bytes message_queue = 5; + * @param value The messageQueue to set. + * @return This builder for chaining. + */ + public Builder setMessageQueue(com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + messageQueue_ = value; + bitField0_ |= 0x00000010; + onChanged(); + return this; + } + /** + *
+       * Block message queue if requested.
+       * 
+ * + * bytes message_queue = 5; + * @return This builder for chaining. + */ + public Builder clearMessageQueue() { + bitField0_ = (bitField0_ & ~0x00000010); + messageQueue_ = getDefaultInstance().getMessageQueue(); + onChanged(); + return this; + } + + private com.google.protobuf.ByteString justification_ = com.google.protobuf.ByteString.EMPTY; + /** + *
+       * Justification if requested.
+       * 
+ * + * bytes justification = 6; + * @return The justification. + */ + @java.lang.Override + public com.google.protobuf.ByteString getJustification() { + return justification_; + } + /** + *
+       * Justification if requested.
+       * 
+ * + * bytes justification = 6; + * @param value The justification to set. + * @return This builder for chaining. + */ + public Builder setJustification(com.google.protobuf.ByteString value) { + if (value == null) { throw new NullPointerException(); } + justification_ = value; + bitField0_ |= 0x00000020; + onChanged(); + return this; + } + /** + *
+       * Justification if requested.
+       * 
+ * + * bytes justification = 6; + * @return This builder for chaining. + */ + public Builder clearJustification() { + bitField0_ = (bitField0_ & ~0x00000020); + justification_ = getDefaultInstance().getJustification(); + onChanged(); + return this; + } + + private boolean isEmptyJustification_ ; + /** + *
+       * True if justification should be treated as present but empty.
+       * This hack is unfortunately necessary because shortcomings in the protobuf format otherwise
+       * doesn't make in possible to differentiate between a lack of justification and an empty
+       * justification.
+       * 
+ * + * bool is_empty_justification = 7; + * @return The isEmptyJustification. + */ + @java.lang.Override + public boolean getIsEmptyJustification() { + return isEmptyJustification_; + } + /** + *
+       * True if justification should be treated as present but empty.
+       * This hack is unfortunately necessary because shortcomings in the protobuf format otherwise
+       * doesn't make in possible to differentiate between a lack of justification and an empty
+       * justification.
+       * 
+ * + * bool is_empty_justification = 7; + * @param value The isEmptyJustification to set. + * @return This builder for chaining. + */ + public Builder setIsEmptyJustification(boolean value) { + + isEmptyJustification_ = value; + bitField0_ |= 0x00000040; + onChanged(); + return this; + } + /** + *
+       * True if justification should be treated as present but empty.
+       * This hack is unfortunately necessary because shortcomings in the protobuf format otherwise
+       * doesn't make in possible to differentiate between a lack of justification and an empty
+       * justification.
+       * 
+ * + * bool is_empty_justification = 7; + * @return This builder for chaining. + */ + public Builder clearIsEmptyJustification() { + bitField0_ = (bitField0_ & ~0x00000040); + isEmptyJustification_ = false; + onChanged(); + return this; + } + @java.lang.Override + public final Builder setUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.setUnknownFields(unknownFields); + } + + @java.lang.Override + public final Builder mergeUnknownFields( + final com.google.protobuf.UnknownFieldSet unknownFields) { + return super.mergeUnknownFields(unknownFields); + } + + + // @@protoc_insertion_point(builder_scope:com.limechain.network.substream.sync.pb.BlockData) + } + + // @@protoc_insertion_point(class_scope:com.limechain.network.substream.sync.pb.BlockData) + private static final com.limechain.network.substream.sync.pb.SyncMessage.BlockData DEFAULT_INSTANCE; + static { + DEFAULT_INSTANCE = new com.limechain.network.substream.sync.pb.SyncMessage.BlockData(); + } + + public static com.limechain.network.substream.sync.pb.SyncMessage.BlockData getDefaultInstance() { + return DEFAULT_INSTANCE; + } + + private static final com.google.protobuf.Parser + PARSER = new com.google.protobuf.AbstractParser() { + @java.lang.Override + public BlockData parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + Builder builder = newBuilder(); + try { + builder.mergeFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(builder.buildPartial()); + } catch (com.google.protobuf.UninitializedMessageException e) { + throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial()); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException(e) + .setUnfinishedMessage(builder.buildPartial()); + } + return builder.buildPartial(); + } + }; + + public static com.google.protobuf.Parser parser() { + return PARSER; + } + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + @java.lang.Override + public com.limechain.network.substream.sync.pb.SyncMessage.BlockData getDefaultInstanceForType() { + return DEFAULT_INSTANCE; + } + + } + + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_com_limechain_network_substream_sync_pb_BlockRequest_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_com_limechain_network_substream_sync_pb_BlockRequest_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_com_limechain_network_substream_sync_pb_BlockResponse_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_com_limechain_network_substream_sync_pb_BlockResponse_fieldAccessorTable; + private static final com.google.protobuf.Descriptors.Descriptor + internal_static_com_limechain_network_substream_sync_pb_BlockData_descriptor; + private static final + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable + internal_static_com_limechain_network_substream_sync_pb_BlockData_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\021SyncMessage.proto\022\'com.limechain.netwo" + + "rk.substream.sync.pb\"\273\001\n\014BlockRequest\022\016\n" + + "\006fields\030\001 \001(\r\022\016\n\004hash\030\002 \001(\014H\000\022\020\n\006number\030" + + "\003 \001(\014H\000\022\020\n\010to_block\030\004 \001(\014\022E\n\tdirection\030\005" + + " \001(\01622.com.limechain.network.substream.s" + + "ync.pb.Direction\022\022\n\nmax_blocks\030\006 \001(\rB\014\n\n" + + "from_block\"S\n\rBlockResponse\022B\n\006blocks\030\001 " + + "\003(\01322.com.limechain.network.substream.sy" + + "nc.pb.BlockData\"\226\001\n\tBlockData\022\014\n\004hash\030\001 " + + "\001(\014\022\016\n\006header\030\002 \001(\014\022\014\n\004body\030\003 \003(\014\022\017\n\007rec" + + "eipt\030\004 \001(\014\022\025\n\rmessage_queue\030\005 \001(\014\022\025\n\rjus" + + "tification\030\006 \001(\014\022\036\n\026is_empty_justificati" + + "on\030\007 \001(\010**\n\tDirection\022\r\n\tAscending\020\000\022\016\n\n" + + "Descending\020\001B)\n\'com.limechain.network.su" + + "bstream.sync.pbb\006proto3" + }; + descriptor = com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }); + internal_static_com_limechain_network_substream_sync_pb_BlockRequest_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_com_limechain_network_substream_sync_pb_BlockRequest_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_com_limechain_network_substream_sync_pb_BlockRequest_descriptor, + new java.lang.String[] { "Fields", "Hash", "Number", "ToBlock", "Direction", "MaxBlocks", "FromBlock", }); + internal_static_com_limechain_network_substream_sync_pb_BlockResponse_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_com_limechain_network_substream_sync_pb_BlockResponse_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_com_limechain_network_substream_sync_pb_BlockResponse_descriptor, + new java.lang.String[] { "Blocks", }); + internal_static_com_limechain_network_substream_sync_pb_BlockData_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_com_limechain_network_substream_sync_pb_BlockData_fieldAccessorTable = new + com.google.protobuf.GeneratedMessageV3.FieldAccessorTable( + internal_static_com_limechain_network_substream_sync_pb_BlockData_descriptor, + new java.lang.String[] { "Hash", "Header", "Body", "Receipt", "MessageQueue", "Justification", "IsEmptyJustification", }); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/src/test/java/com/limechain/network/substream/sync/SyncTest.java b/src/test/java/com/limechain/network/substream/sync/SyncTest.java new file mode 100644 index 000000000..c66da3b97 --- /dev/null +++ b/src/test/java/com/limechain/network/substream/sync/SyncTest.java @@ -0,0 +1,95 @@ +package com.limechain.network.substream.sync; + +import com.google.protobuf.ByteString; +import com.limechain.network.kad.KademliaService; +import com.limechain.network.protocol.sync.SyncService; +import com.limechain.network.substream.sync.pb.SyncMessage; +import io.ipfs.multihash.Multihash; +import io.libp2p.core.Host; +import io.libp2p.core.PeerId; +import io.libp2p.protocol.Ping; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.peergos.HostBuilder; + +import java.util.List; + +import java.util.Random; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class SyncTest { + private Host senderNode = null; + private KademliaService kademliaService = null; + private SyncService syncService = null; + + @BeforeAll + public void init() { + HostBuilder hostBuilder = (new HostBuilder()).generateIdentity() + .listenLocalhost(10000 + new Random().nextInt(50000)); + + syncService = new SyncService("/dot/sync/2"); + kademliaService = new KademliaService("/dot/kad", + Multihash.deserialize(hostBuilder.getPeerId().getBytes()), false); + + hostBuilder.addProtocols(List.of(new Ping(), kademliaService.getDht(), syncService.getSyncMessages())); + senderNode = hostBuilder.build(); + + senderNode.start().join(); + + kademliaService.setHost(senderNode); + } + + @AfterAll + public void stopNode() { + if (senderNode != null) { + senderNode.stop(); + } + } + + @Test + public void remoteBlockRequest_returnCorrectBlock_ifGivenBlockHash() { + var peerId = PeerId.fromBase58("12D3KooWKer8bYqpYjwurVABu13mkELpX2X7mSpEicpjShLeg7D6"); + //CHECKSTYLE.OFF + var receivers = new String[]{"/dns/p2p.4.polkadot.network/tcp/30333/p2p/12D3KooWKer8bYqpYjwurVABu13mkELpX2X7mSpEicpjShLeg7D6"}; + //CHECKSTYLE.ON + int connectedNodes = kademliaService.connectBootNodes(receivers); + int expectedConnectedNodes = 1; + assertEquals(expectedConnectedNodes, connectedNodes); + + //CHECKSTYLE.OFF + var response = syncService.getSyncMessages().remoteBlockRequest(senderNode, senderNode.getAddressBook(), peerId, 19, "cbd3e72e769652f804568a48889382edff4742074a7201309acfd1069e5de90a", + null, null, SyncMessage.Direction.Ascending, 1); + ByteString expected = ByteString.copyFrom(new byte[]{-53, -45, -25, 46, 118, -106, 82, -8, 4, 86, -118, 72, -120, -109, -126, -19, -1, 71, 66, 7, 74, 114, 1, 48, -102, -49, -47, 6, -98, 93, -23, 10}); + //CHECKSTYLE.ON + assertNotNull(response); + assertTrue(response.getBlocksCount() > 0); + + assertEquals(expected, response.getBlocks(0).getHash()); + } + + @Test + public void remoteBlockRequest_returnCorrectBlock_ifGivenBlockNumber() { + var peerId = PeerId.fromBase58("12D3KooWKer8bYqpYjwurVABu13mkELpX2X7mSpEicpjShLeg7D6"); + //CHECKSTYLE.OFF + var receivers = new String[]{"/dns/p2p.4.polkadot.network/tcp/30333/p2p/12D3KooWKer8bYqpYjwurVABu13mkELpX2X7mSpEicpjShLeg7D6"}; + //CHECKSTYLE.ON + int connectedNodes = kademliaService.connectBootNodes(receivers); + int expectedConnectedNodes = 1; + assertEquals(expectedConnectedNodes, connectedNodes); + //CHECKSTYLE.OFF + var response = syncService.getSyncMessages().remoteBlockRequest(senderNode, senderNode.getAddressBook(), peerId, 19, null, + 15000000, 15000000, SyncMessage.Direction.Ascending, 1); + ByteString expected = ByteString.copyFrom(new byte[]{-5, -114, 15, -47, 54, 111, 75, -101, 58, 121, -122, 66, -103, -41, -9, 10, -125, -12, 77, 72, -53, -7, -84, 19, 95, 45, -110, -39, 104, 8, 6, -88}); + //CHECKSTYLE.ON + assertNotNull(response); + assertTrue(response.getBlocksCount() > 0); + + assertEquals(expected, response.getBlocks(0).getHash()); + } +} \ No newline at end of file