Package org.ethereum.net.wire

Source Code of org.ethereum.net.wire.MessageDecoder

package org.ethereum.net.wire;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import org.ethereum.listener.EthereumListener;
import org.ethereum.manager.WorldManager;
import org.ethereum.net.message.Message;
import org.ethereum.net.message.MessageFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.List;

/**
* The PacketDecoder parses every valid Ethereum packet to a Message object
*/
@Component
@Scope("prototype")
public class MessageDecoder extends ByteToMessageDecoder {

    private static final Logger loggerWire = LoggerFactory.getLogger("wire");
    private static final Logger loggerNet = LoggerFactory.getLogger("net");

    @Autowired
    WorldManager worldManager;

  @Override
  protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {

    if (!isValidEthereumPacket(in)) {
      return;
    }

    byte[] encoded = new byte[in.readInt()];
    in.readBytes(encoded);
 
    if (loggerWire.isDebugEnabled())
      loggerWire.debug("Encoded: [{}]", Hex.toHexString(encoded));

    Message msg = MessageFactory.createMessage(encoded);

    if (loggerNet.isInfoEnabled())
            loggerNet.info("From: \t{} \tRecv: \t{}", ctx.channel().remoteAddress(), msg);

        EthereumListener listener = worldManager.getListener();
        listener.onRecvMessage(msg);

    out.add(msg);
        in.markReaderIndex();
    }
 
  private boolean isValidEthereumPacket(ByteBuf in) {
    // Ethereum message is at least 8 bytes
    if (in.readableBytes() < 8)
      return false;

    long syncToken = in.readUnsignedInt();

        if (!((syncToken >> 24   0xFF) == 0x22  &&
              (syncToken >> 16   0xFF) == 0x40  &&
              (syncToken >>  8   0xFF) == 0x08  &&
              (syncToken         &  0xFF) == 0x91 )) {

      // TODO: Drop frame and continue.
      // A collision can happen (although rare)
      // If this happens too often, it's an attack.
      // In that case, drop the peer.
      loggerWire.error("Abandon garbage, wrong sync token: [{}]", syncToken);
    }

    // Don't have the full message yet
        long msgSize = in.getInt(in.readerIndex());
    if (msgSize > in.readableBytes()) {
      loggerWire.trace("msg decode: magicBytes: [{}], readBytes: [{}] / msgSize: [{}] ",
                    syncToken, in.readableBytes(), msgSize);
      in.resetReaderIndex();
      return false;
    }

    loggerWire.trace("Message fully constructed: readBytes: [{}] / msgSize: [{}]", in.readableBytes(), msgSize);
    return true;
  }
}
TOP

Related Classes of org.ethereum.net.wire.MessageDecoder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.