daily pastebin goal
49%
SHARE
TWEET

fpga-cminer 0.1

LazarusLong Jul 9th, 2011 309 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*  fpga-cminer 0.1, Copyright 2011 by Lazarus Long, lazarus-long@gmx.net
  2.  
  3.     This is a bitcoin FPGA miner targeted to embedded linux systems
  4.     based on and FPGA API compatible with TheSevens pyminer.
  5.     If you linke this tool drop in some coins into my hat:
  6.     16EwZRLio5ik6fshWexzuj9jWeWCoNEuHw
  7.  
  8.     This program is free software: you can redistribute it and/or modify
  9.     it under the terms of the GNU General Public License as published by
  10.     the Free Software Foundation, either version 3 of the License, or
  11.     (at your option) any later version.
  12.  
  13.     This program is distributed in the hope that it will be useful,
  14.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.     GNU General Public License for more details.
  17.  
  18.     You should have received a copy of the GNU General Public License
  19.     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20. */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <stdint.h>
  25. #include <ctype.h>
  26. #include <string.h>
  27. #include <unistd.h>
  28. #include <termios.h>
  29. #include <signal.h>
  30. #include <sys/ioctl.h>
  31. #include <sys/stat.h>
  32. #include <sys/time.h>
  33. #include <fcntl.h>
  34.  
  35. #include <curl/curl.h>
  36. #include <json/json.h>
  37.  
  38. #define STRSIZE 256
  39.  
  40. struct curl_response{
  41.     char *data;
  42.     size_t size;
  43. };
  44.  
  45. struct fpga_in_data {
  46.         uint8_t command;
  47.         uint8_t state[32];
  48.         uint8_t data[12];
  49. }  __attribute__ ((packed));
  50.  
  51. struct mining_job {
  52.         struct fpga_in_data in_data;
  53.         uint8_t jobdata[128];
  54.         uint8_t nonce[4];
  55. } __attribute__ ((packed));
  56.  
  57. /* 1 indicates an LP event */
  58. int lp_ctrl=0;
  59. /* 1 indicates child has exited */
  60. int lp_child=0;
  61.  
  62. void print_usage(void) {
  63.         printf("fpga-cminer 0.1, 2011 by Lazarus Long, lazarus-long@gmx.net\n");
  64.         printf("Usage: fpga-cminer -d <device> -u <username> -p <password> [ -j <seconds>]\n");
  65.         printf(" i.e.: fpga-cminer -d /dev/ttyS0 -h btcguild.com  -u lazarus -p heinlein\n");
  66.         printf("                   -j overwrites the job intervall to X seconds\n");
  67. }
  68.  
  69. static int hex2num(char c)
  70. {
  71.         if (c >= '0' && c <= '9')
  72.                 return c - '0';
  73.         if (c >= 'a' && c <= 'f')
  74.                 return c - 'a' + 10;
  75.         if (c >= 'A' && c <= 'F')
  76.                 return c - 'A' + 10;
  77.         return -1;
  78. }
  79.  
  80. static int hex2byte(const char *hex)
  81. {
  82.         int a, b;
  83.         a = hex2num(*hex++);
  84.         if (a < 0)
  85.                 return -1;
  86.         b = hex2num(*hex++);
  87.         if (b < 0)
  88.                 return -1;
  89.         return (a << 4) | b;
  90. }
  91.  
  92. /**
  93.  * hexstr2bin - Convert ASCII hex string into binary data
  94.  * @hex: ASCII hex string (e.g., "01ab")
  95.  * @buf: Buffer for the binary data
  96.  * @len: Length of the text to convert in bytes (of buf); hex will be double
  97.  * this size
  98.  * Returns: 0 on success, -1 on failure (invalid hex string)
  99.  */
  100. int hexstr2bin(const char *hex, uint8_t *buf, size_t len)
  101. {
  102.         size_t i;
  103.         int a;
  104.         const char *ipos = hex;
  105.         uint8_t *opos = buf;
  106.  
  107.         for (i = 0; i < len; i++) {
  108.                 a = hex2byte(ipos);
  109.                 if (a < 0)
  110.                         return -1;
  111.                 *opos++ = a;
  112.                 ipos += 2;
  113.         }
  114.         return 0;
  115. }
  116.  
  117. /**
  118.  * hexstr2binrev - Convert ASCII hex string into binary data in reverse order
  119.  * @hex: ASCII hex string (e.g., "01ab")
  120.  * @buf: Buffer for the binary data
  121.  * @len: Length of the text to convert in bytes (of buf); hex will be double
  122.  * this size
  123.  * Returns: 0 on success, -1 on failure (invalid hex string)
  124.  */
  125. int hexstr2binrev(const char *hex, uint8_t *buf, size_t len)
  126. {
  127.         size_t i;
  128.         int a;
  129.         const char *ipos = hex;
  130.         uint8_t *opos = buf;
  131.  
  132.         /* goto end of string */
  133.         ipos += ((len-1)*2);
  134.  
  135.         for (i = 0; i < len; i++) {
  136.                 a = hex2byte(ipos);
  137.                 if (a < 0)
  138.                         return -1;
  139.                 *opos++ = a;
  140.                 ipos -= 2;
  141.         }
  142.         return 0;
  143. }
  144.  
  145. void print_hex(uint8_t *data, int len) {
  146.         int i;
  147.         for (i=0; i<len; i++) {
  148.  
  149.                 printf("%.2x",data[i]);
  150.         }
  151.         printf("\n");
  152. }
  153.  
  154. static void
  155. signal_handler (int sig)
  156. {
  157.         if (sig == SIGUSR1) {
  158.                 lp_ctrl=1;
  159.                 lp_child=0;
  160.         }
  161.         //if (sig == SIGCHLD) {
  162.         //lp_child=0;
  163.         //}
  164. }
  165.  
  166. size_t header_callback (void *ptr, size_t size, size_t nmemb, void *data)
  167. {
  168.         struct curl_response *header_res = NULL;
  169.         int rsize = 0;
  170.         int lp_size = 0;
  171.         header_res = (struct curl_response *)data;
  172.        
  173.         rsize = size * nmemb;
  174.        
  175.         if (strncmp(ptr,"X-Long-Polling: ",16) ==0) {
  176.                 lp_size=rsize-16;
  177.                 header_res->data = (char *)realloc(header_res->data, header_res->size + lp_size + 1);
  178.                 if (header_res->data) {
  179.                         memcpy(&(header_res->data[header_res->size]), ptr+16, lp_size);
  180.                         header_res->size += lp_size;
  181.                         header_res->data[lp_size] = 0;
  182.                         printf("Found Long polling URL: %s\n",(char *)header_res->data);
  183.                 }
  184.         }
  185.         return rsize;
  186. }
  187.  
  188.  
  189. size_t response_callback(void *ptr,
  190.         size_t size, size_t nmemb, void *data)
  191. {
  192.     int rsize = 0;
  193.     struct curl_response *res = NULL;
  194.     rsize = size * nmemb;
  195.     res = (struct curl_response *)data;
  196.     res->data = (char *)realloc(res->data, res->size + rsize + 1);
  197.     if (res->data) {
  198.         memcpy(&(res->data[res->size]), ptr, rsize);
  199.         res->size += rsize;
  200.         res->data[res->size] = 0;
  201.     }
  202.     return rsize;
  203. }
  204.  
  205. void wait_for_lp(char *lp_url, char *host, char *userpwd) {
  206.         char buf[1024];
  207.         CURL *curl;
  208.         char url[STRSIZE];
  209.         struct curl_slist *slist = NULL;
  210.         struct curl_response res;
  211.  
  212.         curl = curl_easy_init();
  213.         if(curl) {
  214.                 /* init structer for response */
  215.                 res.data = NULL;
  216.                 res.size = 0;
  217.  
  218.                 sprintf(url,"http://%s:8332/LP",host);
  219.                 curl_easy_setopt(curl, CURLOPT_USERPWD, userpwd);
  220.                 curl_easy_setopt(curl, CURLOPT_URL, url);
  221.                 //curl_easy_setopt(curl, CURLOPT_VERBOSE,1);
  222.                 slist = curl_slist_append(slist, "Content-type: application/json");
  223.                 slist = curl_slist_append(slist, "Expect:");
  224.                 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
  225.                 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, response_callback);
  226.  
  227.                 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&res );
  228.                 curl_easy_setopt(curl, CURLOPT_USERAGENT, "fpga-cminer 0.1");
  229.                 curl_easy_perform(curl);
  230.                 curl_slist_free_all(slist);
  231.                
  232.                 char *resp_data=malloc(res.size+2);
  233.                 memset(resp_data,0,res.size+2);
  234.                         snprintf(resp_data,res.size+1,"%s",res.data);
  235.                 free(res.data);
  236.                
  237.                 //printf("LP: %s\n",resp_data);
  238.                 kill(getppid(),SIGUSR1);
  239.  
  240.                 curl_easy_cleanup(curl);
  241.                 free(resp_data);
  242.                 /* XXX: we sould use this job response too */
  243.         }
  244. }
  245.  
  246. void send_response(struct mining_job *job, char *host, char *userpwd) {
  247.  
  248.         char buf[1024];
  249.         struct timeval starttime;
  250.         struct timeval endtime;
  251.         CURL *curl;
  252.         char url[STRSIZE];
  253.         struct curl_slist *slist = NULL;
  254.         struct curl_response res;
  255.  
  256.         curl = curl_easy_init();
  257.         if(curl) {
  258.                 /* init structer for response */
  259.                 res.data = NULL;
  260.                 res.size = 0;
  261.  
  262.                 sprintf(url,"http://%s:8332",host);
  263.                 curl_easy_setopt(curl, CURLOPT_USERPWD, userpwd);
  264.                 curl_easy_setopt(curl, CURLOPT_URL, url);
  265.                 //curl_easy_setopt(curl, CURLOPT_VERBOSE,1);
  266.                 slist = curl_slist_append(slist, "Content-type: application/json");
  267.                 slist = curl_slist_append(slist, "Expect:");
  268.                 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
  269.                 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, response_callback);
  270.                 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&res );
  271.                 curl_easy_setopt(curl, CURLOPT_USERAGENT, "fpga-cminer 0.1");
  272.  
  273.                 json_object *jobj = json_object_new_object();
  274.                 json_object *jmeth = json_object_new_string("getwork");
  275.                 json_object *jid = json_object_new_int(0);
  276.                 json_object *jparams = json_object_new_array();
  277.                 // in: 12 bytes: 75:63:-1
  278.                 //"params": [binascii.hexlify(data[:76] + nonce + data[80:])], "id": 0})
  279.  
  280.                 char *responsedata;
  281.                 responsedata=malloc(1024);
  282.                 int i,j;
  283.                 for (i=0; i<76; i++) {
  284.                         sprintf(responsedata+(i*2),"%.2x",job->jobdata[i]);
  285.                 }
  286.                 sprintf(responsedata+(i*2),"%.2x%.2x%.2x%.2x",
  287.                         job->nonce[0],
  288.                         job->nonce[1],
  289.                         job->nonce[2],
  290.                         job->nonce[3]);
  291.                 i+=4;
  292.                 for (j=i; j<128; j++) {
  293.                         sprintf(responsedata+(j*2),"%.2x",job->jobdata[j]);
  294.                 }
  295.  
  296.                 json_object *jdata = json_object_new_string(responsedata);
  297.  
  298.                 json_object_array_add(jparams,jdata);
  299.                 json_object_object_add(jobj,"method", jmeth);
  300.                 json_object_object_add(jobj,"params", jparams);
  301.                 json_object_object_add(jobj,"id", jid);
  302.  
  303.                 sprintf(buf,"%s",json_object_to_json_string(jobj));
  304.                 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, buf);
  305.  
  306.                 //printf("Response Json: %s\n",buf);
  307.                 curl_easy_perform(curl);
  308.                 curl_slist_free_all(slist);
  309.                
  310.                 char *resp_data=malloc(res.size+2);
  311.                 memset(resp_data,0,res.size+2);
  312.                         snprintf(resp_data,res.size+1,"%s",res.data);
  313.                 // Response: {"id":0,"error":null,"result":false}
  314.                 struct json_object *json_resp;
  315.                 struct json_object *json_result;
  316.                 struct json_object *json_error;
  317.                 json_resp = json_tokener_parse(resp_data);
  318.                 json_result = json_object_object_get(json_resp, "result");
  319.                 json_error = json_object_object_get(json_resp, "error");
  320.                 printf("Result:%s\n",json_object_get_string(json_result));
  321.                 free(res.data);
  322.                 free(resp_data);
  323.                 free(responsedata);
  324.                 curl_easy_cleanup(curl);
  325.         }
  326. }
  327.  
  328. struct mining_job *request_job(char *host, char *userpwd) {
  329.  
  330.         char buf[1024];
  331.         char lp_url[1024];
  332.         struct timeval starttime;
  333.         struct timeval endtime;
  334.         CURL *curl;
  335.         char url[STRSIZE];
  336.         struct curl_slist *slist = NULL;
  337.         struct mining_job *job=NULL;
  338.         struct curl_response res;
  339.         struct curl_response header_res;
  340.  
  341.         curl = curl_easy_init();
  342.         if(curl) {
  343.                 job = malloc(sizeof(struct mining_job));       
  344.                 /* init structer for response */
  345.                 res.data = NULL;
  346.                 res.size = 0;
  347.                 header_res.data = NULL;
  348.                 header_res.size = 0;
  349.  
  350.                 sprintf(url,"http://%s:8332",host);
  351.                 curl_easy_setopt(curl, CURLOPT_USERPWD, userpwd);
  352.                 curl_easy_setopt(curl, CURLOPT_URL, url);
  353.                 //curl_easy_setopt(curl, CURLOPT_VERBOSE,1);
  354.                 slist = curl_slist_append(slist, "Content-type: application/json");
  355.                 slist = curl_slist_append(slist, "Expect:");
  356.                 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
  357.                 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, response_callback);
  358.                 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&res );
  359.                 curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback);
  360.                 curl_easy_setopt(curl, CURLOPT_WRITEHEADER, (void *)&header_res);
  361.                 curl_easy_setopt(curl, CURLOPT_USERAGENT, "fpga-cminer 0.1");
  362.  
  363.                 json_object *jobj = json_object_new_object();
  364.                 json_object *jmeth = json_object_new_string("getwork");
  365.                 json_object *jid = json_object_new_int(0);
  366.                 json_object *jparams = json_object_new_array();
  367.  
  368.                 json_object_object_add(jobj,"method", jmeth);
  369.                 json_object_object_add(jobj,"params", jparams);
  370.                 json_object_object_add(jobj,"id", jid);
  371.  
  372.                 sprintf(buf,"%s",json_object_to_json_string(jobj));
  373.                 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, buf);
  374.  
  375.                 curl_easy_perform(curl);
  376.                 curl_slist_free_all(slist);
  377.                
  378.                 char *resp_data=malloc(res.size+2);
  379.                 memset(resp_data,0,res.size+2);
  380.                         snprintf(resp_data,res.size+1,"%s",res.data);
  381.                 free(res.data);
  382.  
  383.                 char *lp_url=NULL;
  384.                 lp_url=malloc(header_res.size+2);
  385.                 memset(lp_url,0,header_res.size+2);
  386.                         snprintf(lp_url,header_res.size+1,"%s",header_res.data);
  387.                 free(header_res.data);
  388.  
  389.                 struct json_object *json_resp;
  390.                 struct json_object *json_result;
  391.                 struct json_object *json_midstate;
  392.                 struct json_object *json_data;
  393.                 json_resp = json_tokener_parse(resp_data);
  394.                 json_result = json_object_object_get(json_resp, "result");
  395.                 json_midstate = json_object_object_get(json_result, "midstate");
  396.                 json_data = json_object_object_get(json_result, "data");
  397.                 //printf("getwork Json:%s\n",json_object_to_json_string(json_resp));
  398.                 //printf("JSON state:%s\n",json_object_get_string(json_midstate));
  399.                 snprintf(buf,256,"%s",json_object_get_string(json_data));
  400.                 memset(job,0x0,sizeof(struct mining_job));
  401.                 job->in_data.command =0x01;
  402.                 hexstr2bin(json_object_get_string(json_data), job->jobdata, sizeof(job->jobdata));             
  403.                 hexstr2binrev(json_object_get_string(json_midstate),job->in_data.state, sizeof(job->in_data.state));
  404.                 hexstr2binrev(&buf[128],job->in_data.data, sizeof(job->in_data.data));
  405.  
  406.                 curl_easy_cleanup(curl);
  407.                 free(resp_data);
  408.  
  409.                 /* if we do not have a LP child we fork one off now */
  410.                 if ((lp_url == NULL) && (lp_child != 1)) {
  411.                         switch (fork()) {
  412.                         case -1:
  413.                                 printf("LP fork error");
  414.                                 exit(1);
  415.                         case 0:  /* child */
  416.                                 wait_for_lp(lp_url,host,userpwd);
  417.                                 exit(0);
  418.                         default: /* parent */
  419.                                 printf("LP watcher forked\n");
  420.                                 lp_ctrl=0;
  421.                                 lp_child=1;
  422.                         }
  423.                 }
  424.         }
  425.         return job;
  426. }
  427.  
  428. int mine(int tty_fd, struct mining_job *job, float fpgajobint) {
  429.  
  430.         int loop=1;
  431.         int state=0;
  432.         int len=0;
  433.         uint8_t *data=NULL;
  434.         data = malloc(4);
  435.  
  436.         printf("Mining:");
  437.         print_hex((uint8_t *)&(job->in_data),sizeof(struct fpga_in_data));
  438.         if (write (tty_fd, (uint8_t *)&(job->in_data), sizeof(struct fpga_in_data)) != sizeof(struct fpga_in_data)) {
  439.                 printf("write error\n");
  440.                 exit(1);
  441.         }
  442.  
  443.         while(loop) {
  444.                 /* 1: starting
  445.                  * 2: done */
  446.                 len = read (tty_fd, data, 1);
  447.                 if (len > 0) {
  448.                         if (data[0]==0x1) {
  449.                                 //printf("FPGA accepted\n");
  450.                                 state=1;
  451.                         } else if(data[0]==0x2) {
  452.                                 if (state == 0) {
  453.                                         printf("Error: FPGA responded finished out of state\n");
  454.                                         exit(1);
  455.                                 }
  456.                                 loop=0;
  457.                                 len = read (tty_fd, data, 4);
  458.                                 if (len==4) {
  459.                                         job->nonce[0]=data[3];
  460.                                         job->nonce[1]=data[2];
  461.                                         job->nonce[2]=data[1];
  462.                                         job->nonce[3]=data[0];
  463.                                         free(data);
  464.                                         return 1;
  465.                                 } else {
  466.                                         printf("read error in mining loop\n");
  467.                                         break;
  468.                                 }
  469.                         } else {
  470.                                 printf("Error: FPGA responded: 0x%x\n",data[0]);
  471.                                 exit(1);
  472.                         }
  473.                 } else {
  474.                         fpgajobint -= 0.1; /* VTIME 1 */
  475.                         if (fpgajobint <= 0) {
  476.                                 printf("nothing found\n");
  477.                                 break;
  478.                         }
  479.                         if (lp_ctrl>0) {
  480.                                 lp_ctrl=0;
  481.                                 printf("Long Polling indicated new block\n");
  482.                                 break;
  483.                         }
  484.                 }
  485.         }
  486.         if (data != NULL)
  487.                 free(data);
  488.         return(-1);
  489. }
  490.  
  491. int
  492. main(int argc, char **argv)
  493. {
  494.         char buf[1024];
  495.         char userpwd[1024];
  496.         struct timeval starttime;
  497.         struct timeval endtime;
  498.         CURL *curl;
  499.         CURLcode res;
  500.         extern char *optarg;
  501.         extern int optind, opterr;
  502.         char url[STRSIZE];
  503.         char *dev=NULL;
  504.         char *user=NULL;
  505.         char *pass=NULL;
  506.         char *host=NULL;
  507.         int ch;
  508.         int jobint = -1;
  509.         int tty_fd;
  510.         float fpgajobintval=60;
  511.         struct curl_slist *slist = NULL;
  512.  
  513.  
  514.         uint8_t result[4];
  515.  
  516.         struct mining_job *job;
  517.  
  518.         while (1) {
  519.                 ch = getopt(argc, argv, "d:u:p:h:j:");
  520.                 if (ch == -1) {
  521.                         break;
  522.                 }
  523.                 switch (ch) {
  524.                 case 'd':
  525.                         dev = optarg;
  526.                         break;
  527.                 case 'h':
  528.                         host = optarg;
  529.                         break;
  530.                 case 'u':
  531.                         user = optarg;
  532.                         break;
  533.                 case 'p':
  534.                         pass = optarg;
  535.                         break;
  536.                 case 'j':
  537.                         jobint = atoi(optarg);
  538.                         break;
  539.                 default:
  540.                         print_usage();
  541.                         exit(1);
  542.                 }
  543.         }
  544.         if (host == NULL) {
  545.                 print_usage();
  546.                 exit(1);
  547.         }
  548.  
  549.         sprintf(userpwd,"%s:%s",user,pass);
  550.  
  551.         /* install sig handlers, LP chikd will send SIGUSR1 if a new block is started */
  552.         signal (SIGCHLD, signal_handler);
  553.         signal (SIGUSR1, signal_handler);
  554.  
  555.  
  556.         /* serial port stuff */
  557.         tty_fd = open(dev, O_RDWR | O_NOCTTY);
  558.         if (tty_fd < 0) {
  559.                 printf("Could not open serial port: %s\n",dev);
  560.                 exit(1);
  561.         }
  562.         struct termios newtio;
  563.         memset (&newtio, 0, sizeof (newtio));
  564.         /* Set the bitrate */
  565.         cfsetispeed (&newtio, B115200);
  566.         cfsetospeed (&newtio, B115200);
  567.         /* 8N1 */
  568.         newtio.c_cflag |= CS8;
  569.         newtio.c_cflag &= ~PARENB;
  570.         newtio.c_cflag &= (~CSTOPB);
  571.         /* Selects raw (non-canonical) input and output */
  572.         newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
  573.         newtio.c_oflag &= ~OPOST;
  574.         /* Ignore parity errors */
  575.         newtio.c_iflag |= IGNPAR;
  576.         /* Enable receiber, hang on close, ignore control line */
  577.         newtio.c_cflag |= CREAD | HUPCL | CLOCAL;
  578.         /* Read 1 byte minimun, no timeout specified */
  579.         newtio.c_cc[VMIN] = 0;
  580.         newtio.c_cc[VTIME] = 1; /*100ms timeout */
  581.         if (tcsetattr (tty_fd, TCSANOW, &newtio) < 0) {
  582.                 printf("Error on tcsetattr\n");
  583.                 exit(1);
  584.         }      
  585.         if (tcflush (tty_fd, TCIFLUSH) < 0) {
  586.                 printf("Error on tcflush\n");
  587.                 exit(1);
  588.         }
  589.  
  590.         /* detect FPGA */
  591.         int len;
  592.         uint8_t *data=NULL;
  593.         data = malloc(1024);
  594.  
  595.         job = malloc(sizeof(struct mining_job));
  596.         memset(job,0x0,sizeof(struct mining_job));
  597.         if (write (tty_fd, (uint8_t *)&(job->in_data), sizeof(struct fpga_in_data)) != sizeof(struct fpga_in_data)) {
  598.                 printf("write error\n");
  599.                 exit(1);
  600.         }
  601.  
  602.         len = read (tty_fd, data, 100);
  603.         if (len <= 0) {
  604.                 printf("FPGA did not respond\n");
  605.                 exit(1);
  606.         }
  607.         free(data);
  608.  
  609.         printf("FPGA OK, received: %d bytes\n",len);
  610.         printf("Measuring FPGA performance...\n");
  611.  
  612.         job->in_data.command =0x01;
  613.         hexstr2binrev("1625cbf1a5bc6ba648d1218441389e00a9dc79768a2fc6f2b79c70cf576febd0",
  614.                 job->in_data.state, 32);
  615.         hexstr2binrev("4c0afa494de837d81a269421",
  616.                 job->in_data.data, 12);
  617.         gettimeofday(&starttime,0);
  618.         //print_hex(job->in_data.state,32);
  619.         if ((mine(tty_fd,job,fpgajobintval)) < 0) {
  620.                 printf("mine error\n");
  621.                 exit(1);
  622.         }
  623.         gettimeofday(&endtime,0);
  624.  
  625.         /* test mining result */
  626.         hexstr2bin("7bc2b302",result, 4);
  627.         if (memcmp(result,job->nonce,4)!=0) {
  628.                 printf("recv: %d bytes: 0x%.2x%.2x%.2x%.2x\n",
  629.                         len,job->nonce[0],job->nonce[1],job->nonce[2],job->nonce[3]);
  630.                 printf("FPGA did wrong math\n");
  631.                 exit(1);
  632.         } else {
  633.                 float delta;
  634.                 float mhps;
  635.                 delta = endtime.tv_sec-starttime.tv_sec;
  636.                 mhps = 45.335163 / delta;
  637.                 printf("Delta was: %f\n",delta);
  638.                 if (jobint > 0)
  639.                         fpgajobintval = jobint;
  640.                 else
  641.                         fpgajobintval = delta * 94.738 ; /* complete pattern takes 94.738 times the test pattern */
  642.                 printf("FPGA check passed, %f MH/s, Job intervall: %f\n",mhps,fpgajobintval);
  643.         }
  644.  
  645.         while (1) {
  646.                 job = request_job(host,userpwd);
  647.                 if (job == NULL) {
  648.                         printf("Could not get job");
  649.                         exit(1);
  650.                 }
  651.                 if ((mine(tty_fd,job,fpgajobintval)) > 0) {
  652.                         printf("Share found: 0x%.2x%.2x%.2x%.2x\n",
  653.                                 job->nonce[0],job->nonce[1],job->nonce[2],job->nonce[3]);
  654.                         send_response(job,host,userpwd);
  655.                 }
  656.         }
  657.  
  658.         return 0;
  659. }
RAW Paste Data
Top