Package org.litecoinpool.miner

Source Code of org.litecoinpool.miner.Work

package org.litecoinpool.miner;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Work {
 
  private static final int DEFAULT_TIMEOUT = 10000; // ms
 
  private static final Pattern dataPattern = Pattern.compile("\"data\"\\s*:\\s*\"([0-9a-f]+)\"");
  private static final Pattern targetPattern = Pattern.compile("\"target\"\\s*:\\s*\"([0-9a-f]+)\"");
  private static final Pattern resultPattern = Pattern.compile("\"result\"\\s*:\\s*([0-9A-Za-z]+)");
 
  private URL url;
  private String auth;
  private long responseTime;
  private String xLongPolling = null;
 
  private byte[] data; // little-endian
  private byte[] target; // little-endian
  private byte[] header; // big-endian
 
  public Work(URL url, String auth) throws IOException {
    this(url, url, auth);
  }
 
  public Work(URL url, URL mainUrl, String auth) throws IOException {
    this((HttpURLConnection) url.openConnection(), url, auth);
  }

  public Work(HttpURLConnection conn, URL mainUrl, String auth) throws IOException {
      String request = "{\"method\": \"getwork\", \"params\": [], \"id\":0}";
   
      conn = getJsonRpcConnection(conn, request, auth);
      int response = conn.getResponseCode();
      if (response == 401 || response == 403)
        throw new IllegalArgumentException("Access denied");
      String content = getConnectionContent(conn);
     
      responseTime = System.currentTimeMillis();
        Matcher m = dataPattern.matcher(content);
        if (!m.find())
          throw new RuntimeException(content);
      String sData = m.group(1);
      data = hexStringToByteArray(sData);
        m = targetPattern.matcher(content);
        if (!m.find())
          throw new RuntimeException(content);
        String sTarget = m.group(1);
        target= hexStringToByteArray(sTarget);
        header = headerByData(data);
        xLongPolling = conn.getHeaderField("X-Long-Polling");
        this.url = mainUrl;
        this.auth = auth;
  }
 
  public boolean submit(int nonce) throws IOException {
    byte[] d = data.clone();
    d[79] = (byte) (nonce >>  0);
    d[78] = (byte) (nonce >>  8);
    d[77] = (byte) (nonce >> 16);
    d[76] = (byte) (nonce >> 24);
    String sData = byteArrayToHexString(d);
    String request = "{\"method\": \"getwork\", \"params\": [ \"" + sData + "\" ], \"id\":1}";

    HttpURLConnection conn = getJsonRpcConnection(url, request, auth);
      String content = getConnectionContent(conn);
     
        Matcher m = resultPattern.matcher(content);
        if (m.find() && m.group(1).equals("true"))
          return true;
    return false;
  }
 
  public boolean meetsTarget(int nonce, Hasher hasher) throws GeneralSecurityException {
    byte[] hash = hasher.hash(header, nonce);
    for (int i = hash.length - 1; i >= 0; i--) {
      if ((hash[i] & 0xff) > (target[i] & 0xff))
        return false;
      if ((hash[i] & 0xff) < (target[i] & 0xff))
        return true;
    }
    return true;
  }
 
  public byte[] getData() {
    return data;
  }
 
  public byte[] getTarget() {
    return target;
  }
 
  public byte[] getHeader() {
    return header;
  }
 
  public long getResponseTime() {
    return responseTime;
  }
 
  public long getAge() {
    return System.currentTimeMillis() - responseTime;
  }
 
  public URL getLongPollingURL() throws URISyntaxException, MalformedURLException {
    if (xLongPolling == null)
      return null;
    return url.toURI().resolve(xLongPolling).toURL();
  }
 
  private static byte[] headerByData(byte[] data) {
    byte[] h = new byte[80];
    for (int i = 0; i < 80; i += 4) {
      h[i]     = data[i + 3];
      h[i + 1] = data[i + 2];
      h[i + 2] = data[i + 1];
      h[i + 3] = data[i];
    }
    return h;
  }
 
  public static String byteArrayToHexString(byte[] b) {
    StringBuilder sb = new StringBuilder(80);
    for (int i = 0; i < b.length; i++)
      sb.append(Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1));
    return sb.toString();
  }
 
  public static byte[] hexStringToByteArray(String s) {
      int len = s.length();
      byte[] data = new byte[len / 2];
      for (int i = 0; i < len; i += 2) {
          data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                               + Character.digit(s.charAt(i+1), 16));
      }
      return data;
  }
 
  private final static char[] BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
    private static int[] toInt = new int[128];

  static {
    for (int i = 0; i < BASE64_ALPHABET.length; i++) {
      toInt[BASE64_ALPHABET[i]] = i;
    }
  }
 
  public static String stringToBase64(String str) {
    byte[] buf = str.getBytes();
    int size = buf.length;
    char[] ar = new char[((size + 2) / 3) * 4];
    int a = 0;
    int i = 0;
    while (i < size) {
      byte b0 = buf[i++];
      byte b1 = (i < size) ? buf[i++] : 0;
      byte b2 = (i < size) ? buf[i++] : 0;
      ar[a++] = BASE64_ALPHABET[(b0 >> 2) & 0x3f];
      ar[a++] = BASE64_ALPHABET[((b0 << 4) | ((b1 & 0xFF) >> 4)) & 0x3f];
      ar[a++] = BASE64_ALPHABET[((b1 << 2) | ((b2 & 0xFF) >> 6)) & 0x3f];
      ar[a++] = BASE64_ALPHABET[b2 & 0x3f];
    }
    switch (size % 3) {
    case 1:
      ar[--a] = '=';
    case 2:
      ar[--a] = '=';
    }
    return new String(ar);
  }
 
  public static HttpURLConnection getJsonRpcConnection(URL url, String request, String auth) throws IOException {
    return getJsonRpcConnection((HttpURLConnection) url.openConnection(), request, auth);
  }
 
  public static HttpURLConnection getJsonRpcConnection(HttpURLConnection conn, String request, String auth) throws IOException {
    if (conn.getConnectTimeout() == 0)
      conn.setConnectTimeout(DEFAULT_TIMEOUT);
    if (conn.getReadTimeout() == 0)
      conn.setReadTimeout(DEFAULT_TIMEOUT);
      conn.setRequestMethod("POST");
      if (auth != null)
        conn.setRequestProperty("Authorization", "Basic " + stringToBase64(auth));
      conn.setRequestProperty("Content-Type", "application/json");
      conn.setRequestProperty("Content-Length", Integer.toString(request.getBytes().length));
      conn.setRequestProperty("X-Mining-Extensions", "midstate");
      conn.setAllowUserInteraction(false);
      conn.setUseCaches(false);
    conn.setDoOutput(true);
   
    DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
      wr.writeBytes(request);
      wr.close();
        return conn;
  }
 
  public static String getConnectionContent(HttpURLConnection conn) throws IOException {
        InputStream is = conn.getInputStream();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        int len;
        byte[] buffer = new byte[4096];
        while ((len = is.read(buffer)) != -1) {
          bos.write(buffer, 0, len);
        }
      String content = bos.toString();
        is.close();
        return content;
  }

  public static boolean test() {
    try {
      byte[] header = hexStringToByteArray("01000000f615f7ce3b4fc6b8f61e8f89aedb1d0852507650533a9e3b10b9bbcc30639f279fcaa86746e1ef52d3edb3c4ad8259920d509bd073605c9bf1d59983752a6b06b817bb4ea78e011d012d59d4");
      byte[] hash = new Hasher().hash(header);
      return byteArrayToHexString(hash).equals("d9eb8663ffec241c2fb118adb7de97a82c803b6ff46d57667935c81001000000");
    } catch (GeneralSecurityException e) {
      return false;
    }
  }
 
}
TOP

Related Classes of org.litecoinpool.miner.Work

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.