Kevacoin stratum server for solo-mining
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
2.3 KiB

9 years ago
package rpc
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"time"
"../pool"
)
type RPCClient struct {
url string
client *http.Client
}
type GetBlockTemplateReply struct {
Blob string `json:"blocktemplate_blob"`
Difficulty int64 `json:"difficulty"`
ReservedOffset int `json:"reserved_offset"`
Height int64 `json:"height"`
PrevHash string `json:"prev_hash"`
}
type JSONRpcResp struct {
Id *json.RawMessage `json:"id"`
Result *json.RawMessage `json:"result"`
Error map[string]interface{} `json:"error"`
}
func NewRPCClient(cfg *pool.Config) *RPCClient {
url := fmt.Sprintf("http://%s:%v/json_rpc", cfg.Daemon.Host, cfg.Daemon.Port)
rpcClient := &RPCClient{url: url}
timeout, _ := time.ParseDuration(cfg.Daemon.Timeout)
rpcClient.client = &http.Client{
Timeout: timeout,
}
return rpcClient
}
func (r *RPCClient) GetBlockTemplate(reserveSize int, address string) (GetBlockTemplateReply, error) {
params := map[string]interface{}{"reserve_size": reserveSize, "wallet_address": address}
rpcResp, err := r.doPost(r.url, "getblocktemplate", params)
var reply GetBlockTemplateReply
if err != nil {
return reply, err
}
if rpcResp.Error != nil {
return reply, errors.New(string(rpcResp.Error["message"].(string)))
}
err = json.Unmarshal(*rpcResp.Result, &reply)
return reply, err
}
func (r *RPCClient) SubmitBlock(hash string) (JSONRpcResp, error) {
rpcResp, err := r.doPost(r.url, "submitblock", []string{hash})
if err != nil {
return rpcResp, err
}
if rpcResp.Error != nil {
return rpcResp, errors.New(string(rpcResp.Error["message"].(string)))
}
return rpcResp, nil
}
func (r *RPCClient) doPost(url string, method string, params interface{}) (JSONRpcResp, error) {
jsonReq := map[string]interface{}{"id": "0", "method": method, "params": params}
data, _ := json.Marshal(jsonReq)
req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
req.Header.Set("Content-Length", (string)(len(data)))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
resp, err := r.client.Do(req)
var rpcResp JSONRpcResp
if err != nil {
return rpcResp, err
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
err = json.Unmarshal(body, &rpcResp)
return rpcResp, err
}