@Override
 public Map callServer(RpcRequest rpcRequest) {
   try {
     herder.take(configuration);
     logger.tracef("id=%d, took: %s", getId(), configuration);
     return callServer(rpcRequest, configuration);
   } catch (Exception e) {
     throw BitcoindCallException.wrap(e);
   } finally {
     herder.offer(configuration);
     logger.tracef("id=%d, offer: %s", getId(), configuration);
   }
 }
 private void shutdown() {
   bitcoindProcessManager.shutdown();
   addressManager.shutdown();
   bitcoindFacadeFactory.shutdown();
   hiddenServerLogic.shutdown();
   rollingProfitParticipantLogic.shutdown();
   logger.info("shutdown");
 }
  private Injector startup() {
    Injector injector;
    while (true) {
      try {
        injector = Guice.createInjector(new CommonModule(), new HiddenServerModule());

        addressManager = injector.getInstance(AddressManager.class);
        addressManager.start();

        // restart will use -rescan parameter so new imported addresses are available
        bitcoindProcessManager = injector.getInstance(BitcoindProcessManager.class);
        if (!bitcoindProcessManager.startAllBitcoindInstances()) {
          throw new RuntimeException("bitcoind instances not up");
        }
        bitcoindProcessManager.start();

        hiddenServerLogic = injector.getInstance(HiddenServerLogic.class);
        hiddenServerLogic.start();

        rollingProfitParticipantLogic = injector.getInstance(RollingProfitParticipantLogic.class);
        rollingProfitParticipantLogic.start();

        bitcoindFacadeFactory = injector.getInstance(BitcoindFacadeFactory.class);

        // consider testing profit & change addresses in P50PotConfig

        return injector;
      } catch (Throwable e) {
        logger.error("oh noes", e);
        try {
          Thread.sleep(2000);
        } catch (InterruptedException e1) {
          Thread.currentThread().interrupt();
          throw new RuntimeException(e1);
        }
      }
    }
  }