gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/stratumminer/siadclient.go (about)

     1  package stratumminer
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"net/http"
     9  )
    10  
    11  // SiadClient is a simple client to a siad
    12  type SiadClient struct {
    13  	siadurl string
    14  }
    15  
    16  func decodeMessage(resp *http.Response) (msg string, err error) {
    17  	buf, err := ioutil.ReadAll(resp.Body)
    18  	if err != nil {
    19  		return
    20  	}
    21  	var data struct {
    22  		Message string `json:"message"`
    23  	}
    24  	if err = json.Unmarshal(buf, &data); err == nil {
    25  		msg = data.Message
    26  	}
    27  	return
    28  }
    29  
    30  //Start does nothing
    31  func (sc *SiadClient) Start() {}
    32  
    33  //Stop does nothing
    34  func (sc *SiadClient) Stop() {}
    35  
    36  // Connected is always true if we're using a local node
    37  func (sc *SiadClient) Connected() bool { return true }
    38  
    39  //SetDeprecatedJobCall does nothing
    40  func (sc *SiadClient) SetDeprecatedJobCall(call DeprecatedJobCall) {}
    41  
    42  //GetHeaderForWork fetches new work from the SIA daemon
    43  func (sc *SiadClient) GetHeaderForWork() (target []byte, header []byte, deprecationChannel chan bool, job interface{}, err error) {
    44  	//the deprecationChannel is not used but return a valid channel anyway
    45  	deprecationChannel = make(chan bool)
    46  
    47  	client := &http.Client{}
    48  
    49  	req, err := http.NewRequest("GET", sc.siadurl, nil)
    50  	if err != nil {
    51  		return
    52  	}
    53  
    54  	req.Header.Add("User-Agent", "SiaPrime-Agent")
    55  	resp, err := client.Do(req)
    56  	if err != nil {
    57  		return
    58  	}
    59  	defer resp.Body.Close()
    60  	switch resp.StatusCode {
    61  	case 200:
    62  	case 400:
    63  		msg, errd := decodeMessage(resp)
    64  		if errd != nil {
    65  			err = fmt.Errorf("Status code %d", resp.StatusCode)
    66  		} else {
    67  			err = fmt.Errorf("Status code %d, message: %s", resp.StatusCode, msg)
    68  		}
    69  		return
    70  	default:
    71  		err = fmt.Errorf("Status code %d", resp.StatusCode)
    72  		return
    73  	}
    74  	buf, err := ioutil.ReadAll(resp.Body)
    75  	if err != nil {
    76  		return
    77  	}
    78  
    79  	if len(buf) < 112 {
    80  		err = fmt.Errorf("Invalid response, only received %d bytes", len(buf))
    81  		return
    82  	}
    83  
    84  	target = buf[:32]
    85  	header = buf[32:112]
    86  
    87  	return
    88  }
    89  
    90  //SubmitHeader reports a solved header to the SIA daemon
    91  func (sc *SiadClient) SubmitHeader(header []byte, job interface{}) (err error) {
    92  	req, err := http.NewRequest("POST", sc.siadurl, bytes.NewReader(header))
    93  	if err != nil {
    94  		return
    95  	}
    96  
    97  	req.Header.Add("User-Agent", "SiaPrime-Agent")
    98  
    99  	client := &http.Client{}
   100  	resp, err := client.Do(req)
   101  	if err != nil {
   102  		return
   103  	}
   104  	switch resp.StatusCode {
   105  	case 204:
   106  	default:
   107  		msg, errd := decodeMessage(resp)
   108  		if errd != nil {
   109  			err = fmt.Errorf("Status code %d", resp.StatusCode)
   110  		} else {
   111  			err = fmt.Errorf("%s", msg)
   112  		}
   113  		return
   114  	}
   115  	return
   116  }