Пример #1
0
  /**
   * Called when a pool send a notify request.
   *
   * @param pool
   * @param setDifficulty
   */
  public void onPoolNotify(Pool pool, MiningNotifyNotification notify) {
    if (notify.getCleanJobs()) {
      LOGGER.info("New block detected on pool {}.", pool.getName());
    }

    MiningNotifyNotification notification = new MiningNotifyNotification();
    notification.setBitcoinVersion(notify.getBitcoinVersion());
    notification.setCleanJobs(notify.getCleanJobs());
    notification.setCoinbase1(notify.getCoinbase1());
    notification.setCoinbase2(notify.getCoinbase2());
    notification.setCurrentNTime(notify.getCurrentNTime());
    notification.setJobId(notify.getJobId());
    notification.setMerkleBranches(notify.getMerkleBranches());
    notification.setNetworkDifficultyBits(notify.getNetworkDifficultyBits());
    notification.setPreviousHash(notify.getPreviousHash());

    Set<WorkerConnection> connections = getPoolWorkerConnections(pool);

    if (connections == null || connections.isEmpty()) {
      LOGGER.debug("No worker connections on pool {}. Do not send notify.", pool.getName());
    } else {
      for (WorkerConnection connection : connections) {
        connection.onPoolNotify(notification);
      }
    }
  }
Пример #2
0
 /** Called by pool when its state changes */
 public void onPoolStateChange(Pool pool) {
   if (pool.isReady()) {
     LOGGER.warn("Pool {} is UP.", pool.getName());
     poolSwitchingStrategyManager.onPoolUp(pool);
   } else {
     LOGGER.warn("Pool {} is DOWN. Moving connections to another one.", pool.getName());
     poolSwitchingStrategyManager.onPoolDown(pool);
   }
 }
Пример #3
0
  /**
   * Called when a pool set the difficulty.
   *
   * @param pool
   * @param setDifficulty
   */
  public void onPoolSetDifficulty(Pool pool, MiningSetDifficultyNotification setDifficulty) {
    LOGGER.info("Set difficulty {} on pool {}.", setDifficulty.getDifficulty(), pool.getName());

    MiningSetDifficultyNotification notification = new MiningSetDifficultyNotification();
    notification.setDifficulty(setDifficulty.getDifficulty());

    Set<WorkerConnection> connections = getPoolWorkerConnections(pool);

    if (connections == null || connections.isEmpty()) {
      LOGGER.debug("No worker connections on pool {}. Do not send setDifficulty.", pool.getName());
    } else {
      for (WorkerConnection connection : connections) {
        connection.onPoolDifficultyChanged(notification);
      }
    }
  }
Пример #4
0
 /**
  * Return the pool based on the pool name.
  *
  * @param poolHost
  * @return
  */
 public Pool getPool(String poolName) {
   Pool result = null;
   synchronized (pools) {
     for (Pool pool : pools) {
       if (pool.getName().toString().equals(poolName)) {
         result = pool;
         break;
       }
     }
   }
   return result;
 }
Пример #5
0
  /**
   * Disable/Enable the pool with the given name
   *
   * @param poolName
   * @param isEnabled
   * @throws NoPoolAvailableException
   */
  public void setPoolEnabled(String poolName, boolean isEnabled)
      throws NoPoolAvailableException, Exception {
    Pool pool = getPool(poolName);
    if (pool == null) {
      throw new NoPoolAvailableException("Pool with name " + poolName + " is not found");
    }

    if (pool.isEnabled() != isEnabled) {
      LOGGER.info("Set pool {} {}", pool.getName(), isEnabled ? "enabled" : "disabled");
      pool.setEnabled(isEnabled, this);
    }
  }
Пример #6
0
  /**
   * Called when a pool has sent a message to show.
   *
   * @param showMessage
   */
  public void onPoolShowMessage(Pool pool, ClientShowMessageNotification showMessage) {
    LOGGER.info(
        "\n*****************************\nMessage from pool {}: {}\n*****************************",
        pool.getName(),
        showMessage.getMessage());
    Set<WorkerConnection> connections = getPoolWorkerConnections(pool);

    if (connections != null && !connections.isEmpty()) {
      for (WorkerConnection connection : connections) {
        connection.onPoolShowMessage(showMessage);
      }
    }
  }
Пример #7
0
  /**
   * Called when a pool set the extranonce
   *
   * @param pool
   * @param setExtranonce
   */
  public void onPoolSetExtranonce(Pool pool, MiningSetExtranonceNotification setExtranonce) {
    LOGGER.info("Set the extranonce on pool {}.", pool.getName());

    Set<WorkerConnection> connections = getPoolWorkerConnections(pool);

    if (connections == null || connections.isEmpty()) {
      LOGGER.debug("No worker connections on pool {}. Do not send setExtranonce.", pool.getName());
    } else {
      for (WorkerConnection connection : connections) {
        try {
          connection.onPoolExtranonceChange();
        } catch (ChangeExtranonceNotSupportedException e) {
          connection.close();
          onWorkerDisconnection(
              connection,
              new Exception(
                  "The workerConnection "
                      + connection.getConnectionName()
                      + " does not support setExtranonce notification."));
        }
      }
    }
  }
Пример #8
0
  /**
   * To call when a subscribe request is received on a worker connection. Return the pool on which
   * the connection is bound.
   *
   * @param connection
   * @param request
   */
  public Pool onSubscribeRequest(WorkerConnection connection, MiningSubscribeRequest request)
      throws NoPoolAvailableException {
    Pool pool = poolSwitchingStrategyManager.getPoolForConnection(connection);

    Set<WorkerConnection> workerConnections = getPoolWorkerConnections(pool);
    workerConnections.add(connection);
    this.workerConnections.add(connection);
    LOGGER.info(
        "New WorkerConnection {} subscribed. {} connections active on pool {}.",
        connection.getConnectionName(),
        workerConnections.size(),
        pool.getName());

    return pool;
  }
Пример #9
0
 /** Start all pools. */
 public void startPools(List<Pool> pools) {
   this.pools = Collections.synchronizedList(new ArrayList<Pool>(pools));
   synchronized (pools) {
     for (Pool pool : pools) {
       try {
         if (pool.isEnabled()) {
           pool.startPool(this);
         } else {
           LOGGER.warn("Do not start pool {} since it is disabled.", pool.getName());
         }
       } catch (Exception e) {
         LOGGER.error("Failed to start the pool {}.", pool, e);
       }
     }
   }
 }
Пример #10
0
  /**
   * Switch the given connection to the given pool.
   *
   * @param connection
   * @param newPool
   */
  public void switchPoolForConnection(WorkerConnection connection, Pool newPool)
      throws TooManyWorkersException, ChangeExtranonceNotSupportedException {
    // If the old pool is the same as the new pool, do nothing.
    if (!newPool.equals(connection.getPool())) {
      // Remove the connection from the old pool connection list.
      Set<WorkerConnection> oldPoolConnections = getPoolWorkerConnections(connection.getPool());
      if (oldPoolConnections != null) {
        oldPoolConnections.remove(connection);
      }

      // Then rebind the connection to this pool. An exception is thrown
      // if the rebind fails since the connection does not support the
      // extranonce change.
      connection.rebindToPool(newPool);

      // And finally add the worker connection to the pool's worker
      // connections
      Set<WorkerConnection> newPoolConnections = getPoolWorkerConnections(newPool);
      newPoolConnections.add(connection);

      // Ask to the pool to authorize the worker
      // Create a fake authorization request since when a connection is
      // rebound, the miner does not send auhtorization request (since it
      // has already done it). But it may be the first time this
      // connection is bound to this pool, so the username on this
      // connection is not yet authorized on the pool.
      for (Entry<String, String> entry : connection.getAuthorizedWorkers().entrySet()) {
        MiningAuthorizeRequest fakeRequest = new MiningAuthorizeRequest();
        fakeRequest.setUsername(entry.getKey());
        fakeRequest.setPassword(entry.getValue());
        try {
          onAuthorizeRequest(connection, fakeRequest);
        } catch (AuthorizationException e) {
          LOGGER.error(
              "Authorization of user {} failed on pool {} when rebinding connection {}. Closing the connection. Cause: {}",
              entry.getKey(),
              newPool.getName(),
              connection.getConnectionName(),
              e.getMessage());
          connection.close();
        }
      }
    }
  }
Пример #11
0
  /**
   * Set the priority of the pool with the given name and rebind worker connections based on this
   * new priority.
   *
   * @param poolName
   * @param newPriority
   * @throws BadParameterException
   */
  public void setPoolPriority(String poolName, int newPriority)
      throws NoPoolAvailableException, BadParameterException {
    if (getPool(poolName) == null) {
      throw new NoPoolAvailableException("Pool with name " + poolName + " not found");
    }

    if (newPriority < 0) {
      throw new BadParameterException("The priority has to be higher or equal to 0");
    }

    Pool pool = getPool(poolName);
    LOGGER.info(
        "Changing pool {} priority from {} to {}.",
        pool.getName(),
        pool.getPriority(),
        newPriority);
    pool.setPriority(newPriority);

    poolSwitchingStrategyManager.onPoolUpdated(pool);
  }
Пример #12
0
  /**
   * Add the pool described in the given poolDTO
   *
   * @param addPoolDTO
   * @return
   * @throws URISyntaxException
   * @throws PoolStartException
   * @throws SocketException
   */
  public Pool addPool(AddPoolDTO addPoolDTO)
      throws BadParameterException, SocketException, PoolStartException, URISyntaxException {

    LOGGER.debug("Trying to add pool {}.", addPoolDTO);

    checkAddPoolParameters(addPoolDTO);

    Pool poolToAdd =
        new Pool(
            addPoolDTO.getPoolName(),
            addPoolDTO.getPoolHost(),
            addPoolDTO.getUsername(),
            addPoolDTO.getPassword());

    // By default, does not enable extranonce subscribe.
    poolToAdd.setExtranonceSubscribeEnabled(
        addPoolDTO.getEnableExtranonceSubscribe() != null
            && addPoolDTO.getEnableExtranonceSubscribe());

    poolToAdd.setAppendWorkerNames(
        addPoolDTO.getAppendWorkerNames() != null ? addPoolDTO.getAppendWorkerNames() : false);
    poolToAdd.setWorkerSeparator(
        addPoolDTO.getWorkerNameSeparator() != null
            ? addPoolDTO.getWorkerNameSeparator()
            : Constants.DEFAULT_WORKER_NAME_SEPARTOR);
    poolToAdd.setUseWorkerPassword(
        addPoolDTO.getUseWorkerPassword() != null ? addPoolDTO.getUseWorkerPassword() : false);

    if (addPoolDTO.getPriority() != null) {
      poolToAdd.setPriority(addPoolDTO.getPriority());
    }

    if (addPoolDTO.getWeight() != null) {
      poolToAdd.setWeight(addPoolDTO.getWeight());
    }

    // Add the pool to the pool list
    pools.add(poolToAdd);

    if (addPoolDTO.getPriority() != null) {
      try {
        setPoolPriority(addPoolDTO.getPoolName(), addPoolDTO.getPriority());
      } catch (NoPoolAvailableException e) {
        LOGGER.error("BUG DETECTED !!! This exceptin should not happen.", e);
      }
    }

    LOGGER.info("Pool added {}.", addPoolDTO);

    try {
      poolToAdd.setEnabled(addPoolDTO.getIsEnabled() == null || addPoolDTO.getIsEnabled());
    } catch (Exception e) {
      throw new PoolStartException(
          "Failed to enable the created pool with name "
              + poolToAdd.getName()
              + ". This should not happen. Surely a BUUUUGGGG !!!!",
          e);
    }

    if (poolToAdd.isEnabled()) {
      poolToAdd.startPool(this);
    }

    poolSwitchingStrategyManager.onPoolAdded(poolToAdd);

    return poolToAdd;
  }
Пример #13
0
 /**
  * Called when a pool is now stable.
  *
  * @param pool
  */
 public void onPoolStable(Pool pool) {
   LOGGER.warn("Pool {} is STABLE.", pool.getName());
   poolSwitchingStrategyManager.onPoolStable(pool);
 }