Package com.diablominer.DiabloMiner

Source Code of com.diablominer.DiabloMiner.DiabloMiner

/*
* DiabloMiner - OpenCL miner for Bitcoin
* Copyright (C) 2010, 2011, 2012 Patrick McFarland <diablod3@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.diablominer.DiabloMiner;

import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.Proxy.Type;
import java.net.URL;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Formatter;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;

import com.diablominer.DiabloMiner.DeviceState.DeviceState;
import com.diablominer.DiabloMiner.DeviceState.GPUHardwareType;
import com.diablominer.DiabloMiner.NetworkState.JSONRPCNetworkState;
import com.diablominer.DiabloMiner.NetworkState.NetworkState;

public class DiabloMiner {
  public final static long TWO32 = 4294967295L;
  public final static long TIME_OFFSET = 7500;

  NetworkState networkStateHead = null;
  NetworkState networkStateTail = null;
  Proxy proxy = null;
  int workLifetime = 5000;

  boolean debug = false;
  boolean debugtimer = false;

  double GPUTargetFPS = 30.0;
  double GPUTargetFPSBasis;
  int GPUForceWorkSize = 0;
  Integer GPUVectors[] = null;
  boolean GPUNoArray = false;
  boolean GPUDebugSource = false;

  String source;

  AtomicBoolean running = new AtomicBoolean(true);
  List<Thread> threads = new ArrayList<Thread>();

  long startTime;

  AtomicLong blocks = new AtomicLong(0);
  AtomicLong attempts = new AtomicLong(0);
  AtomicLong rejects = new AtomicLong(0);
  AtomicLong hwErrors = new AtomicLong(0);
  Set<String> enabledDevices = null;
  AtomicLong hashCount = new AtomicLong(0);

  final static String CLEAR = "                                                                             ";

  public static void main(String[] args) throws Exception {
    DiabloMiner diabloMiner = new DiabloMiner();

    try {
      diabloMiner.execute(args);
    } catch(DiabloMinerFatalException e) {
      System.exit(-1);
    }
  }

  void execute(String[] args) throws Exception {
    threads.add(Thread.currentThread());

    Options options = new Options();
    options.addOption("u", "user", true, "bitcoin host username");
    options.addOption("p", "pass", true, "bitcoin host password");
    options.addOption("o", "host", true, "bitcoin host IP");
    options.addOption("r", "port", true, "bitcoin host port");
    options.addOption("l", "url", true, "bitcoin host url");
    options.addOption("x", "proxy", true, "optional proxy settings IP:PORT<:username:password>");
    options.addOption("g", "worklifetime", true, "maximum work lifetime in seconds");
    options.addOption("d", "debug", false, "enable debug output");
    options.addOption("dt", "debugtimer", false, "run for 1 minute and quit");
    options.addOption("D", "devices", true, "devices to enable, default all");
    options.addOption("f", "fps", true, "target GPU execution timing");
    options.addOption("na", "noarray", false, "turn GPU kernel array off");
    options.addOption("v", "vectors", true, "vector size in GPU kernel");
    options.addOption("w", "worksize", true, "override GPU worksize");
    options.addOption("ds", "ksource", false, "output GPU kernel source and quit");
    options.addOption("h", "help", false, "this help");

    PosixParser parser = new PosixParser();

    CommandLine line = null;

    try {
      line = parser.parse(options, args);

      if(line.hasOption("help")) {
        throw new ParseException("");
      }
    } catch(ParseException e) {
      System.out.println(e.getLocalizedMessage() + "\n");
      HelpFormatter formatter = new HelpFormatter();
      formatter.printHelp("DiabloMiner -u myuser -p mypassword [args]\n", "", options, "\nRemember to set rpcuser and rpcpassword in your ~/.bitcoin/bitcoin.conf " + "before starting bitcoind or bitcoin --daemon");
      return;
    }

    String splitUrl[] = null;
    String splitUser[] = null;
    String splitPass[] = null;
    String splitHost[] = null;
    String splitPort[] = null;

    if(line.hasOption("url"))
      splitUrl = line.getOptionValue("url").split(",");

    if(line.hasOption("user"))
      splitUser = line.getOptionValue("user").split(",");

    if(line.hasOption("pass"))
      splitPass = line.getOptionValue("pass").split(",");

    if(line.hasOption("host"))
      splitHost = line.getOptionValue("host").split(",");

    if(line.hasOption("port"))
      splitPort = line.getOptionValue("port").split(",");

    int networkStatesCount = 0;

    if(splitUrl != null)
      networkStatesCount = splitUrl.length;

    if(splitUser != null)
      networkStatesCount = Math.max(splitUser.length, networkStatesCount);

    if(splitPass != null)
      networkStatesCount = Math.max(splitPass.length, networkStatesCount);

    if(splitHost != null)
      networkStatesCount = Math.max(splitHost.length, networkStatesCount);

    if(splitPort != null)
      networkStatesCount = Math.max(splitPort.length, networkStatesCount);

    if(networkStatesCount == 0) {
      error("You forgot to give any bitcoin connection info, please add either -l, or -u -p -o and -r");
      System.exit(-1);
    }

    int j = 0;

    for(int i = 0; j < networkStatesCount; i++, j++) {
      String protocol = "http";
      String host = "localhost";
      int port = 8332;
      String path = "/";
      String user = "diablominer";
      String pass = "diablominer";
      byte hostChain = 0;

      if(splitUrl != null && splitUrl.length > i) {
        String[] usernameFix = splitUrl[i].split("@", 3);
        if(usernameFix.length > 2)
          splitUrl[i] = usernameFix[0] + "+++++" + usernameFix[1] + "@" + usernameFix[2];

        URL url = new URL(splitUrl[i]);

        if(url.getProtocol() != null && url.getProtocol().length() > 1)
          protocol = url.getProtocol();

        if(url.getHost() != null && url.getHost().length() > 1)
          host = url.getHost();

        if(url.getPort() != -1)
          port = url.getPort();

        if(url.getPath() != null && url.getPath().length() > 1)
          path = url.getPath();

        if(url.getUserInfo() != null && url.getUserInfo().length() > 1) {
          String[] userPassSplit = url.getUserInfo().split(":");

          user = userPassSplit[0].replace("+++++", "@");

          if(userPassSplit.length > 1 && userPassSplit[1].length() > 1)
            pass = userPassSplit[1];
        }
      }

      if(splitUser != null && splitUser.length > i)
        user = splitUser[i];

      if(splitPass != null && splitPass.length > i)
        pass = splitPass[i];

      if(splitHost != null && splitHost.length > i)
        host = splitHost[i];

      if(splitPort != null && splitPort.length > i)
        port = Integer.parseInt(splitPort[i]);

      NetworkState networkState;

      try {
        networkState = new JSONRPCNetworkState(this, new URL(protocol, host, port, path), user, pass, hostChain);
      } catch(MalformedURLException e) {
        throw new DiabloMinerFatalException(this, "Malformed connection paramaters");
      }

      if(networkStateHead == null) {
        networkStateHead = networkStateTail = networkState;
      } else {
        networkStateTail.setNetworkStateNext(networkState);
        networkStateTail = networkState;
      }
    }

    networkStateTail.setNetworkStateNext(networkStateHead);

    if(line.hasOption("proxy")) {
      final String[] proxySettings = line.getOptionValue("proxy").split(":");

      if(proxySettings.length >= 2) {
        proxy = new Proxy(Type.HTTP, new InetSocketAddress(proxySettings[0], Integer.valueOf(proxySettings[1])));
      }

      if(proxySettings.length >= 3) {
        Authenticator.setDefault(new Authenticator() {
          protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(proxySettings[2], proxySettings[3].toCharArray());
          }
        });
      }
    }

    if(line.hasOption("worklifetime"))
      workLifetime = Integer.parseInt(line.getOptionValue("worklifetime")) * 1000;

    if(line.hasOption("debug"))
      debug = true;

    if(line.hasOption("debugtimer"))
      debugtimer = true;
 

    if(line.hasOption("devices")) {
      String devices[] = line.getOptionValue("devices").split(",");
      enabledDevices = new HashSet<String>();
      for(String s : devices) {
        enabledDevices.add(s);

        if(Integer.parseInt(s) == 0) {
          error("Do not use 0 with -D, devices start at 1");
          System.exit(-1);
        }
      }
    }

    if(line.hasOption("fps")) {
      GPUTargetFPS = Float.parseFloat(line.getOptionValue("fps"));

      if(GPUTargetFPS < 0.1) {
        error("--fps argument is too low, adjusting to 0.1");
        GPUTargetFPS = 0.1;
      }
    }

    if(line.hasOption("noarray"))
      GPUNoArray = true;
   

    if(line.hasOption("worksize"))
      GPUForceWorkSize = Integer.parseInt(line.getOptionValue("worksize"));

    if(line.hasOption("vectors")) {
      String tempVectors[] = line.getOptionValue("vectors").split(",");

      GPUVectors = new Integer[tempVectors.length];

      try {
        for(int i = 0; i < GPUVectors.length; i++) {
          GPUVectors[i] = Integer.parseInt(tempVectors[i]);

          if(GPUVectors[i] > 16) {
            error("DiabloMiner now uses comma-seperated vector layouts, use those instead");
            System.exit(-1);
          } else if(GPUVectors[i] != 1 && GPUVectors[i] != 2 && GPUVectors[i] != 3 && GPUVectors[i] != 4 && GPUVectors[i] != 8 && GPUVectors[i] != 16) {
            error(GPUVectors[i] + " is not a vector length of 1, 2, 3, 4, 8, or 16");
            System.exit(-1);
          }
        }

        Arrays.sort(GPUVectors, Collections.reverseOrder());
      } catch(NumberFormatException e) {
        error("Cannot parse --vector argument(s)");
        System.exit(-1);
      }
    } else {
      GPUVectors = new Integer[1];
      GPUVectors[0] = 1;
    }

    if(line.hasOption("ds"))
      GPUDebugSource = true;

    info("Started");

    StringBuilder list = new StringBuilder(networkStateHead.getQueryUrl().toString());
    NetworkState networkState = networkStateHead.getNetworkStateNext();

    while(networkState != networkStateHead) {
      list.append(", " + networkState.getQueryUrl());
      networkState = networkState.getNetworkStateNext();
    }

    info("Connecting to: " + list);

    long previousHashCount = 0;
    double previousAdjustedHashCount = 0.0;
    long previousAdjustedStartTime = startTime = (now()) - 1;
    StringBuilder hashMeter = new StringBuilder(80);
    Formatter hashMeterFormatter = new Formatter(hashMeter);

    int deviceCount = 0;

    List<List<? extends DeviceState>> allDeviceStates = new ArrayList<List<? extends DeviceState>>();

    List<? extends DeviceState> GPUDeviceStates = new GPUHardwareType(this).getDeviceStates();
    deviceCount += GPUDeviceStates.size();
    allDeviceStates.add(GPUDeviceStates);

    while(running.get()) {
      for(List<? extends DeviceState> deviceStates : allDeviceStates) {
        for(DeviceState deviceState : deviceStates) {
          deviceState.checkDevice();
        }
      }

      long now = now();
      long currentHashCount = hashCount.get();
      double adjustedHashCount = (double) (currentHashCount - previousHashCount) / (double) (now - previousAdjustedStartTime);
      double hashLongCount = (double) currentHashCount / (double) (now - startTime) / 1000.0;

      if(now - startTime > TIME_OFFSET * 2) {
        double averageHashCount = (adjustedHashCount + previousAdjustedHashCount) / 2.0 / 1000.0;

        hashMeter.setLength(0);

        if(!debug) {
          hashMeterFormatter.format("\rmhash: %.1f/%.1f | accept: %d | reject: %d | hw error: %d", averageHashCount, hashLongCount, blocks.get(), rejects.get(), hwErrors.get());
        } else {
          hashMeterFormatter.format("\rmh: %.1f/%.1f | a/r/hwe: %d/%d/%d | gh: ", averageHashCount, hashLongCount, blocks.get(), rejects.get(), hwErrors.get());

          double basisAverage = 0.0;

          for(List<? extends DeviceState> deviceStates : allDeviceStates) {
            for(DeviceState deviceState : deviceStates) {
              hashMeterFormatter.format("%.1f ", deviceState.getDeviceHashCount() / 1000.0 / 1000.0 / 1000.0);
              basisAverage += deviceState.getBasis();
            }
          }

          basisAverage = 1000 / (basisAverage / deviceCount);

          hashMeterFormatter.format("| fps: %.1f", basisAverage);
        }

        System.out.print(hashMeter);
      } else {
        System.out.print("\rWaiting...");
      }

      if(now() - TIME_OFFSET * 2 > previousAdjustedStartTime) {
        previousHashCount = currentHashCount;
        previousAdjustedHashCount = adjustedHashCount;
        previousAdjustedStartTime = now - 1;
      }

      if(debugtimer && now() > startTime + 60 * 1000) {
        System.out.print("\n");
        info("Debug timer is up, quitting...");
        System.exit(0);
      }

      try {
        if(now - startTime > TIME_OFFSET)
          Thread.sleep(1000);
        else
          Thread.sleep(1);
      } catch(InterruptedException e) {
      }
    }

    hashMeterFormatter.close();
  }

  public static int rot(int x, int y) {
    return (x >>> y) | (x << (32 - y));
  }

  public static void sharound(int out[], int na, int nb, int nc, int nd, int ne, int nf, int ng, int nh, int x, int K) {
    int a = out[na];
    int b = out[nb];
    int c = out[nc];
    int d = out[nd];
    int e = out[ne];
    int f = out[nf];
    int g = out[ng];
    int h = out[nh];

    int t1 = h + (rot(e, 6) ^ rot(e, 11) ^ rot(e, 25)) + ((e & f) ^ ((~e) & g)) + K + x;
    int t2 = (rot(a, 2) ^ rot(a, 13) ^ rot(a, 22)) + ((a & b) ^ (a & c) ^ (b & c));

    out[nd] = d + t1;
    out[nh] = t1 + t2;
  }

  public static String dateTime() {
    return "[" + DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM).format(new Date()) + "]";
  }

  public void info(String msg) {
    System.out.println("\r" + CLEAR + "\r" + dateTime() + " " + msg);
    threads.get(0).interrupt();
  }

  public void debug(String msg) {
    if(debug) {
      System.out.println("\r" + CLEAR + "\r" + dateTime() + " DEBUG: " + msg);
      threads.get(0).interrupt();
    }
  }

  public void error(String msg) {
    System.err.println("\r" + CLEAR + "\r" + dateTime() + " ERROR: " + msg);
    threads.get(0).interrupt();
  }

  public void addThread(Thread thread) {
    threads.add(thread);
  }

  public long incrementBlocks() {
    return blocks.incrementAndGet();
  }

  public long incrementAttempts() {
    return attempts.incrementAndGet();
  }

  public long incrementRejects() {
    return rejects.incrementAndGet();
  }

  public long incrementHWErrors() {
    return hwErrors.incrementAndGet();
  }

  public long addAndGetHashCount(long delta) {
    return hashCount.addAndGet(delta);
  }

  public static long now() {
    return System.nanoTime() / 1000000;
  }

  public void halt() {
    running.set(false);

    for(int i = 0; i < threads.size(); i++) {
      Thread thread = threads.get(i);
      if(thread != Thread.currentThread())
        thread.interrupt();
    }
  }

  public boolean getDebug() {
    return debug;
  }

  public Set<String> getEnabledDevices() {
    return enabledDevices;
  }

  public NetworkState getNetworkStateHead() {
    return networkStateHead;
  }

  public Proxy getProxy() {
    return proxy;
  }

  public int getWorkLifetime() {
    return workLifetime;
  }

  public boolean getRunning() {
    return running.get();
  }

  public double getGPUTargetFPS() {
    return GPUTargetFPS;
  }

  public int getGPUForceWorkSize() {
    return GPUForceWorkSize;
  }

  public Integer[] getGPUVectors() {
    return GPUVectors;
  }

  public boolean getGPUNoArray() {
    return GPUNoArray;
  }

  public boolean getGPUDebugSource() {
    return GPUDebugSource;
  }
}
TOP

Related Classes of com.diablominer.DiabloMiner.DiabloMiner

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.