use of org.ethereum.net.message.Message in project rskj by rsksmart.
the class WriterMessageRecorderTest method filterMessage.
@Test
public void filterMessage() throws IOException {
Message message = createRskMessage();
StringWriter writer = new StringWriter();
BufferedWriter bwriter = new BufferedWriter(writer);
List<String> commands = new ArrayList<>();
commands.add("TRANSACTIONS");
MessageFilter filter = new MessageFilter(commands);
Random random = new Random();
byte[] nodeId = new byte[10];
random.nextBytes(nodeId);
NodeID sender = new NodeID(nodeId);
WriterMessageRecorder recorder = new WriterMessageRecorder(bwriter, filter);
recorder.recordMessage(sender, message);
bwriter.close();
String result = writer.toString();
Assert.assertEquals(0, result.length());
}
use of org.ethereum.net.message.Message in project rskj by rsksmart.
the class WriterMessageRecorderTest method recordEthMessage.
@Test
public void recordEthMessage() throws IOException {
Message message = createEthMessage();
StringWriter writer = new StringWriter();
BufferedWriter bwriter = new BufferedWriter(writer);
WriterMessageRecorder recorder = new WriterMessageRecorder(bwriter, null);
recorder.recordMessage(null, message);
bwriter.close();
String result = writer.toString();
String encoded = Hex.toHexString(message.getEncoded());
Assert.assertTrue(result.contains("," + encoded));
Assert.assertTrue(result.contains(",0,TRANSACTIONS,,"));
}
use of org.ethereum.net.message.Message in project rskj by rsksmart.
the class MessageQueue method sendToWire.
private void sendToWire(MessageRoundtrip messageRoundtrip) {
if (messageRoundtrip != null && messageRoundtrip.getRetryTimes() == 0) {
// TODO: retry logic. See messageRoundtrip.hasToRetry
Message msg = messageRoundtrip.getMsg();
ctx.writeAndFlush(msg).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
if (msg.getAnswerMessage() != null) {
messageRoundtrip.incRetryTimes();
messageRoundtrip.saveTime();
}
}
}
use of org.ethereum.net.message.Message in project rskj by rsksmart.
the class MessageQueue method receivedMessage.
public void receivedMessage(Message msg) throws InterruptedException {
MessageRoundtrip messageRoundtrip = requestQueue.peek();
if (messageRoundtrip != null) {
Message waitingMessage = messageRoundtrip.getMsg();
if (waitingMessage instanceof PingMessage) {
hasPing = false;
}
if (waitingMessage.getAnswerMessage() != null && msg.getClass() == waitingMessage.getAnswerMessage()) {
messageRoundtrip.answer();
if (waitingMessage instanceof EthMessage) {
channel.getPeerStats().pong(messageRoundtrip.lastTimestamp);
}
logger.trace("Message round trip covered: [{}] ", messageRoundtrip.getMsg().getClass());
}
}
}
use of org.ethereum.net.message.Message in project rskj by rsksmart.
the class HandshakeHandler method decodeHandshake.
// consume handshake, producing no resulting message to upper layers
private void decodeHandshake(final ChannelHandlerContext ctx, ByteBuf buffer) throws Exception {
if (handshake.isInitiator()) {
if (frameCodec == null) {
byte[] responsePacket = new byte[AuthResponseMessage.getLength() + ECIESCoder.getOverhead()];
if (!buffer.isReadable(responsePacket.length)) {
return;
}
buffer.readBytes(responsePacket);
try {
// trying to decode as pre-EIP-8
AuthResponseMessage response = handshake.handleAuthResponse(myKey, initiatePacket, responsePacket);
loggerNet.trace("From: \t{} \tRecv: \t{}", ctx.channel().remoteAddress(), response);
} catch (Throwable t) {
// it must be format defined by EIP-8 then
responsePacket = readEIP8Packet(buffer, responsePacket);
if (responsePacket == null) {
return;
}
AuthResponseMessageV4 response = handshake.handleAuthResponseV4(myKey, initiatePacket, responsePacket);
loggerNet.trace("From: \t{} \tRecv: \t{}", ctx.channel().remoteAddress(), response);
}
EncryptionHandshake.Secrets secrets = this.handshake.getSecrets();
this.frameCodec = new FrameCodec(secrets);
loggerNet.trace("auth exchange done");
channel.sendHelloMessage(ctx, frameCodec, Hex.toHexString(nodeId), null);
} else {
loggerWire.debug("MessageCodec: Buffer bytes: " + buffer.readableBytes());
List<Frame> frames = frameCodec.readFrames(buffer);
if (frames == null || frames.isEmpty()) {
return;
}
Frame frame = frames.get(0);
byte[] payload = ByteStreams.toByteArray(frame.getStream());
if (frame.getType() == P2pMessageCodes.HELLO.asByte()) {
HelloMessage helloMessage = new HelloMessage(payload);
loggerNet.trace("From: \t{} \tRecv: \t{}", ctx.channel().remoteAddress(), helloMessage);
isHandshakeDone = true;
this.channel.publicRLPxHandshakeFinished(ctx, frameCodec, helloMessage);
recordSuccessfulHandshake(ctx);
} else {
DisconnectMessage message = new DisconnectMessage(payload);
loggerNet.trace("From: \t{} \tRecv: \t{}", channel, message);
channel.getNodeStatistics().nodeDisconnectedRemote(message.getReason());
}
}
} else {
loggerWire.debug("Not initiator.");
if (frameCodec == null) {
loggerWire.debug("FrameCodec == null");
byte[] authInitPacket = new byte[AuthInitiateMessage.getLength() + ECIESCoder.getOverhead()];
if (!buffer.isReadable(authInitPacket.length)) {
return;
}
buffer.readBytes(authInitPacket);
this.handshake = new EncryptionHandshake();
byte[] responsePacket;
try {
// trying to decode as pre-EIP-8
AuthInitiateMessage initiateMessage = handshake.decryptAuthInitiate(authInitPacket, myKey);
loggerNet.trace("From: \t{} \tRecv: \t{}", ctx.channel().remoteAddress(), initiateMessage);
AuthResponseMessage response = handshake.makeAuthInitiate(initiateMessage, myKey);
loggerNet.trace("To: \t{} \tSend: \t{}", ctx.channel().remoteAddress(), response);
responsePacket = handshake.encryptAuthResponse(response);
} catch (Throwable t) {
// it must be format defined by EIP-8 then
try {
authInitPacket = readEIP8Packet(buffer, authInitPacket);
if (authInitPacket == null) {
return;
}
AuthInitiateMessageV4 initiateMessage = handshake.decryptAuthInitiateV4(authInitPacket, myKey);
loggerNet.trace("From: \t{} \tRecv: \t{}", ctx.channel().remoteAddress(), initiateMessage);
AuthResponseMessageV4 response = handshake.makeAuthInitiateV4(initiateMessage, myKey);
loggerNet.trace("To: \t{} \tSend: \t{}", ctx.channel().remoteAddress(), response);
responsePacket = handshake.encryptAuthResponseV4(response);
} catch (InvalidCipherTextException ce) {
loggerNet.warn("Can't decrypt AuthInitiateMessage from " + ctx.channel().remoteAddress() + ". Most likely the remote peer used wrong public key (NodeID) to encrypt message.");
return;
}
}
handshake.agreeSecret(authInitPacket, responsePacket);
EncryptionHandshake.Secrets secrets = this.handshake.getSecrets();
this.frameCodec = new FrameCodec(secrets);
ECPoint remotePubKey = this.handshake.getRemotePublicKey();
byte[] compressed = remotePubKey.getEncoded(false);
this.remoteId = new byte[compressed.length - 1];
System.arraycopy(compressed, 1, this.remoteId, 0, this.remoteId.length);
channel.setNode(remoteId);
final ByteBuf byteBufMsg = ctx.alloc().buffer(responsePacket.length);
byteBufMsg.writeBytes(responsePacket);
ctx.writeAndFlush(byteBufMsg).sync();
} else {
List<Frame> frames = frameCodec.readFrames(buffer);
if (frames == null || frames.isEmpty()) {
return;
}
Frame frame = frames.get(0);
Message message = new P2pMessageFactory().create((byte) frame.getType(), ByteStreams.toByteArray(frame.getStream()));
loggerNet.trace("From: \t{} \tRecv: \t{}", ctx.channel().remoteAddress(), message);
if (frame.getType() == P2pMessageCodes.DISCONNECT.asByte()) {
loggerNet.info("Active remote peer disconnected right after handshake.");
return;
}
if (frame.getType() != P2pMessageCodes.HELLO.asByte()) {
throw new RuntimeException("The message type is not HELLO or DISCONNECT: " + message);
}
HelloMessage inboundHelloMessage = (HelloMessage) message;
// Secret authentication finish here
channel.sendHelloMessage(ctx, frameCodec, Hex.toHexString(nodeId), inboundHelloMessage);
isHandshakeDone = true;
this.channel.publicRLPxHandshakeFinished(ctx, frameCodec, inboundHelloMessage);
recordSuccessfulHandshake(ctx);
}
}
channel.getNodeStatistics().rlpxInHello.add();
}
Aggregations