@Override
  public void catchUp(List<BID> inventory, int limit, boolean headers, final TrunkListener listener)
      throws BCSAPIException {
    log.trace("catchUp");
    ConnectorMessage m;
    try (ConnectorSession session = connection.createSession()) {
      ConnectorProducer transactionRequestProducer =
          session.createProducer(session.createQueue("catchUpRequest"));

      m = session.createMessage();
      BCSAPIMessage.CatchUpRequest.Builder builder = BCSAPIMessage.CatchUpRequest.newBuilder();
      builder.setLimit(limit);
      builder.setHeaders(true);
      for (BID hash : inventory) {
        builder.addInventory(ByteString.copyFrom(hash.unsafeGetArray()));
      }
      m.setPayload(builder.build().toByteArray());
      byte[] response = synchronousRequest(session, transactionRequestProducer, m);
      if (response != null) {
        BCSAPIMessage.TrunkUpdate blockMessage = BCSAPIMessage.TrunkUpdate.parseFrom(response);
        List<APIBlock> blockList = new ArrayList<>();
        for (BCSAPIMessage.BLK b : blockMessage.getAddedList()) {
          blockList.add(APIBlock.fromProtobuf(b));
        }
        listener.trunkUpdate(blockList);
      }
    } catch (ConnectorException | HyperLedgerException | InvalidProtocolBufferException e) {
      throw new BCSAPIException(e);
    }
  }
  @Override
  public APIBlock getBlock(BID hash) throws BCSAPIException {
    try (ConnectorSession session = connection.createSession()) {
      log.trace("get block " + hash);

      ConnectorProducer blockRequestProducer =
          session.createProducer(session.createQueue("blockRequest"));

      ConnectorMessage m = session.createMessage();
      BCSAPIMessage.Hash.Builder builder = BCSAPIMessage.Hash.newBuilder();
      builder.addHash(ByteString.copyFrom(hash.unsafeGetArray()));
      m.setPayload(builder.build().toByteArray());
      byte[] response = synchronousRequest(session, blockRequestProducer, m);
      if (response != null) {
        return APIBlock.fromProtobuf(BCSAPIMessage.BLK.parseFrom(response));
      }
    } catch (ConnectorException | HyperLedgerException | InvalidProtocolBufferException e) {
      throw new BCSAPIException(e);
    }

    return null;
  }
 @Override
 public void registerTrunkListener(final TrunkListener listener) throws BCSAPIException {
   try {
     addTopicListener(
         "trunk",
         listener,
         body -> {
           List<APIBlock> blockList = null;
           try {
             BCSAPIMessage.TrunkUpdate blockMessage = BCSAPIMessage.TrunkUpdate.parseFrom(body);
             blockList = new ArrayList<>();
             for (BCSAPIMessage.BLK b : blockMessage.getAddedList()) {
               blockList.add(APIBlock.fromProtobuf(b));
             }
           } catch (Exception e) {
             log.error("Block message error", e);
           }
           return blockList;
         },
         blocks -> listener.trunkUpdate(blocks));
   } catch (ConnectorException e) {
     throw new BCSAPIException(e);
   }
 }