Skip to content
This repository has been archived by the owner on Aug 23, 2020. It is now read-only.

adds milestone request to message protocol #1829

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/main/java/com/iota/iri/network/neighbor/Neighbor.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.iota.iri.network.protocol.Handshake;
import com.iota.iri.network.protocol.Heartbeat;
import com.iota.iri.network.protocol.MilestoneRequest;

import java.io.IOException;
import java.nio.ByteBuffer;
Expand Down Expand Up @@ -47,6 +48,13 @@ public interface Neighbor {
*/
Heartbeat heartbeat() throws IOException;

/**
* Instructs the {@link Neighbor} to read from its source channel a {@link MilestoneRequest} packet.
* @return The {@link MilestoneRequest} object.
* @throws IOException thrown when reading from the source channel fails
*/
MilestoneRequest milestoneRequest() throws IOException;

/**
* Instructs the {@link Neighbor} to send the given {@link ByteBuffer} to its destination channel.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ private enum ReadState {
private MessageReader msgReader;
private Handshake handshake = new Handshake();
private Heartbeat heartbeat = new Heartbeat();
private MilestoneRequest milestoneRequest = new MilestoneRequest();

/**
* Creates a new {@link NeighborImpl} using the given channel.
Expand Down Expand Up @@ -92,6 +93,11 @@ public Heartbeat heartbeat() throws IOException {
return heartbeat;
}

public MilestoneRequest milestoneRequest() throws IOException{
read();
return milestoneRequest;
}

@Override
public int read() throws IOException {
int bytesRead = msgReader.readMessage(channel);
Expand Down Expand Up @@ -166,6 +172,9 @@ private void handleMessage(ByteBuffer msg) {
case HEARTBEAT:
heartbeat = Heartbeat.fromByteBuffer(msg);
break;
case MS_REQUEST:
milestoneRequest = MilestoneRequest.fromByteBuffer(msg);
break;
default:
// do nothing
}
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/com/iota/iri/network/protocol/MilestoneRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.iota.iri.network.protocol;

import java.nio.ByteBuffer;

/**
* Defines the information contained in a milestone request
*/
public class MilestoneRequest {

private int milestoneIndex;

/**
* Parses the given message into a {@link MilestoneRequest} object.
*
* @param msg the buffer containing the milestone request info
* @return the {@link MilestoneRequest} object
*/
public static MilestoneRequest fromByteBuffer(ByteBuffer msg) {
MilestoneRequest milestoneRequest = new MilestoneRequest();
milestoneRequest.setMilestoneIndex(msg.getInt());
return milestoneRequest;
}

/**
* Gets the milestone index of the milestone request
*
* @return The milestone index
*/
public int getMilestoneIndex() {
return milestoneIndex;
}

/**
* Sets the milestone index of the milestone request
*
* @param milestoneIndex The milestone index
*/
public void setMilestoneIndex(int milestoneIndex) {
this.milestoneIndex = milestoneIndex;
}
}
14 changes: 14 additions & 0 deletions src/main/java/com/iota/iri/network/protocol/Protocol.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ public class Protocol {
*/
public final static byte PROTOCOL_HEARTBEAT_BYTES_LENGTH = 8;

/**
* The amount of byes to store the index of the milestone to request
*/
public final static byte PROTOCOL_MS_REQUEST_BYTES_LENGTH = 4;

/**
* Parses the given buffer into a {@link ProtocolHeader}.
*
Expand Down Expand Up @@ -123,6 +128,15 @@ public static ByteBuffer createHeartbeatPacket(Heartbeat heartbeat) {
return buf;
}

public static ByteBuffer createMilestoneRequestPacket(MilestoneRequest milestoneRequest){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final short payloadLengthBytes = Protocol.PROTOCOL_MS_REQUEST_BYTES_LENGTH;
ByteBuffer buf = ByteBuffer.allocate(ProtocolMessage.HEADER.getMaxLength() + payloadLengthBytes);
addProtocolHeader(buf, ProtocolMessage.MS_REQUEST, payloadLengthBytes);
buf.putInt(milestoneRequest.getMilestoneIndex());
buf.flip();
return buf;
}

/**
* Adds the protocol header to the given {@link ByteBuffer}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public enum ProtocolMessage {
TRANSACTION_GOSSIP((byte) 2, (short) (Protocol.GOSSIP_REQUESTED_TX_HASH_BYTES_LENGTH + TransactionTruncator.NON_SIG_TX_PART_BYTES_LENGTH
+ TransactionTruncator.SIG_DATA_MAX_BYTES_LENGTH), true),

HEARTBEAT((byte) 3, Protocol.PROTOCOL_HEARTBEAT_BYTES_LENGTH, true);
HEARTBEAT((byte) 3, Protocol.PROTOCOL_HEARTBEAT_BYTES_LENGTH, true),
MS_REQUEST((byte) 4, Protocol.PROTOCOL_MS_REQUEST_BYTES_LENGTH, true);

private static final ProtocolMessage[] lookup = new ProtocolMessage[256];

Expand All @@ -47,6 +48,7 @@ public enum ProtocolMessage {
lookup[1] = HANDSHAKE;
lookup[2] = TRANSACTION_GOSSIP;
lookup[3] = HEARTBEAT;
lookup[4] = MS_REQUEST;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public static MessageReader create(ProtocolMessage protoMsg) throws UnknownMessa
case HANDSHAKE:
case TRANSACTION_GOSSIP:
case HEARTBEAT:
case MS_REQUEST:
return create(protoMsg, protoMsg.getMaxLength());
// there might be message types in the future which need a separate message reader implementation
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,13 @@
import com.iota.iri.network.neighbor.Neighbor;
import com.iota.iri.network.neighbor.NeighborState;
import com.iota.iri.network.pipeline.TransactionProcessingPipeline;
import com.iota.iri.network.protocol.Handshake;
import com.iota.iri.network.protocol.*;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;

import com.iota.iri.network.protocol.Heartbeat;
import com.iota.iri.network.protocol.Protocol;
import com.iota.iri.network.protocol.ProtocolMessage;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
Expand Down Expand Up @@ -267,4 +264,60 @@ public int read(ByteBuffer dst) {
fail("didnt expect an exception: " + e.getMessage());
}
}

@Test
public void writeMilestoneRequest() {
MilestoneRequest milestoneRequest = new MilestoneRequest();
milestoneRequest.setMilestoneIndex(1);
ByteBuffer milestoneRequestPacket = Protocol.createMilestoneRequestPacket(milestoneRequest);

Neighbor neighbor = new NeighborImpl<>(selector, new FakeChannel() {

@Override
public int write(ByteBuffer buf) {
int bytesWritten = 0;
while (buf.hasRemaining()) {
buf.get();
bytesWritten++;
}
return bytesWritten;
}
}, localAddr, serverSocketPort, pipeline);

neighbor.send(milestoneRequestPacket);

try {
assertEquals("should have written the entire milestone request packet", milestoneRequestPacket.capacity(), neighbor.write());
} catch (IOException e) {
fail("Didn't expect an exception: " + e.getMessage());
}
}

@Test
public void readMilestoneRequest() {
MilestoneRequest milestoneRequest = new MilestoneRequest();
milestoneRequest.setMilestoneIndex(1);
ByteBuffer milestoneRequestPacket = Protocol.createMilestoneRequestPacket(milestoneRequest);

Neighbor neighbor = new NeighborImpl<>(selector, new FakeChannel() {
// fake having a heartbeat packet in the socket
@Override
public int read(ByteBuffer dst) {
while (dst.hasRemaining()) {
dst.put(milestoneRequestPacket.get());
}
return 0;
}
}, localAddr, serverSocketPort, pipeline);

// set the neighbor as ready for other messages
neighbor.setState(NeighborState.READY_FOR_MESSAGES);

try {
MilestoneRequest readMilestoneRequest = neighbor.milestoneRequest();
assertEquals("milestone index of sent and read ms request should be equal", readMilestoneRequest.getMilestoneIndex(), milestoneRequest.getMilestoneIndex());
} catch (IOException e) {
fail("Didn't expect an exception: " + e.getMessage());
}
}
}
26 changes: 26 additions & 0 deletions src/test/java/com/iota/iri/network/protocol/ProtocolTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,30 @@ public void parseHeartbeat() {
fail("didn't expect any exceptions");
}
}

@Test
public void createMilestoneRequestPacket(){
MilestoneRequest milestoneRequest = new MilestoneRequest();
milestoneRequest.setMilestoneIndex(1);

ByteBuffer buf = Protocol.createMilestoneRequestPacket(milestoneRequest);
final int expectedMessageSize = Protocol.PROTOCOL_MS_REQUEST_BYTES_LENGTH;
assertEquals("buffer should have the right capacity",
Protocol.PROTOCOL_HEADER_BYTES_LENGTH + expectedMessageSize, buf.capacity());
assertEquals("should be of type milestone request message", ProtocolMessage.MS_REQUEST.getTypeID(), buf.get());
assertEquals("should have correct message length", expectedMessageSize, buf.getShort());
}

@Test
public void parseMilestoneRequest() {
try {
ByteBuffer buf = ByteBuffer.allocate(Protocol.PROTOCOL_MS_REQUEST_BYTES_LENGTH);
buf.putInt(1);
buf.flip();
MilestoneRequest milestoneRequest = MilestoneRequest.fromByteBuffer(buf);
assertEquals("should have correct milestone index", milestoneRequest.getMilestoneIndex(), 1);
} catch (Exception e) {
fail("Didn't expect any exceptions: " + e.getMessage());
}
}
}