@Override
  protected void encode(ChannelHandlerContext ctx, FrameCodec.Frame frame, ByteBuf out)
      throws Exception {

    frameCodec.writeFrame(frame, out);

    channel.getNodeStatistics().rlpxOutMessages.add();
  }
 @Override
 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
   if (channel.isDiscoveryMode()) {
     loggerNet.trace("FrameCodec failed: ", cause);
   } else {
     if (cause instanceof IOException) {
       loggerNet.debug("FrameCodec failed: " + ctx.channel().remoteAddress(), cause);
     } else {
       loggerNet.warn("FrameCodec failed: ", cause);
     }
   }
   ctx.close();
 }
  protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out)
      throws IOException {
    if (in.readableBytes() == 0) {
      loggerWire.trace("in.readableBytes() == 0");
      return;
    }

    loggerWire.trace("Decoding frame (" + in.readableBytes() + " bytes)");
    List<FrameCodec.Frame> frames = frameCodec.readFrames(in);

    // Check if a full frame was available.  If not, we'll try later when more bytes come in.
    if (frames == null || frames.isEmpty()) return;

    for (int i = 0; i < frames.size(); i++) {
      FrameCodec.Frame frame = frames.get(i);

      channel.getNodeStatistics().rlpxInMessages.add();
    }

    out.addAll(frames);
  }