Skip to content

Commit ec58d6b

Browse files
committed
Use rpcclient w/ ntfns instead of polling.
1 parent c520a0a commit ec58d6b

File tree

5 files changed

+144
-282
lines changed

5 files changed

+144
-282
lines changed

getwork.go

Lines changed: 0 additions & 230 deletions
Original file line numberDiff line numberDiff line change
@@ -3,184 +3,13 @@
33
package main
44

55
import (
6-
"bytes"
7-
"crypto/tls"
8-
"crypto/x509"
9-
"encoding/binary"
10-
"encoding/hex"
116
"encoding/json"
127
"fmt"
13-
"io"
14-
"math/big"
15-
"net"
16-
"net/http"
17-
"os"
18-
"time"
198

20-
"github.com/decred/go-socks/socks"
219
"github.com/decred/gominer/stratum"
22-
"github.com/decred/gominer/util"
2310
"github.com/decred/gominer/work"
2411
)
2512

26-
// newHTTPClient returns a new HTTP client that is configured according to the
27-
// proxy and TLS settings in the associated connection configuration.
28-
func newHTTPClient(cfg *config) (*http.Client, error) {
29-
// Configure proxy if needed.
30-
var dial func(network, addr string) (net.Conn, error)
31-
if cfg.Proxy != "" {
32-
proxy := &socks.Proxy{
33-
Addr: cfg.Proxy,
34-
Username: cfg.ProxyUser,
35-
Password: cfg.ProxyPass,
36-
}
37-
dial = func(network, addr string) (net.Conn, error) {
38-
c, err := proxy.Dial(network, addr)
39-
if err != nil {
40-
return nil, err
41-
}
42-
return c, nil
43-
}
44-
}
45-
46-
// Configure TLS if needed.
47-
var tlsConfig *tls.Config
48-
if !cfg.NoTLS && cfg.RPCCert != "" {
49-
pem, err := os.ReadFile(cfg.RPCCert)
50-
if err != nil {
51-
return nil, err
52-
}
53-
54-
pool := x509.NewCertPool()
55-
pool.AppendCertsFromPEM(pem)
56-
tlsConfig = &tls.Config{
57-
RootCAs: pool,
58-
InsecureSkipVerify: cfg.TLSSkipVerify,
59-
}
60-
}
61-
62-
// Create and return the new HTTP client potentially configured with a
63-
// proxy and TLS.
64-
client := http.Client{
65-
Transport: &http.Transport{
66-
Dial: dial,
67-
TLSClientConfig: tlsConfig,
68-
},
69-
}
70-
return &client, nil
71-
}
72-
73-
type getWorkResponseJson struct {
74-
Result struct {
75-
Data string
76-
Target string
77-
}
78-
Error *struct {
79-
Code int
80-
Message string
81-
}
82-
}
83-
84-
type getWorkSubmitResponseJson struct {
85-
Result bool
86-
Error *struct {
87-
Code int
88-
Message string
89-
}
90-
}
91-
92-
const (
93-
MaxIdleConnections int = 20
94-
RequestTimeout int = 5
95-
)
96-
97-
// GetWork makes a getwork RPC call and returns the result (data and target).
98-
func GetWork() (*work.Work, error) {
99-
// Generate a request to the configured RPC server.
100-
protocol := "http"
101-
if !cfg.NoTLS {
102-
protocol = "https"
103-
}
104-
url := protocol + "://" + cfg.RPCServer
105-
jsonStr := []byte(`{"jsonrpc": "2.0", "method": "getwork", "params": [], "id": 1}`)
106-
bodyBuff := bytes.NewBuffer(jsonStr)
107-
httpRequest, err := http.NewRequest("POST", url, bodyBuff)
108-
if err != nil {
109-
return nil, err
110-
}
111-
httpRequest.Close = true
112-
httpRequest.Header.Set("Content-Type", "application/json")
113-
114-
// Configure basic access authorization.
115-
httpRequest.SetBasicAuth(cfg.RPCUser, cfg.RPCPassword)
116-
117-
// Create the new HTTP client that is configured according to the user-
118-
// specified options and submit the request.
119-
httpClient, err := newHTTPClient(cfg)
120-
if err != nil {
121-
return nil, err
122-
}
123-
httpResponse, err := httpClient.Do(httpRequest)
124-
if err != nil {
125-
return nil, err
126-
}
127-
128-
body, err := io.ReadAll(httpResponse.Body)
129-
httpResponse.Body.Close()
130-
if err != nil {
131-
err = fmt.Errorf("error reading json reply: %w", err)
132-
return nil, err
133-
}
134-
135-
if httpResponse.Status != "200 OK" {
136-
return nil, fmt.Errorf("http status %s: %s", httpResponse.Status, body)
137-
}
138-
139-
var res getWorkResponseJson
140-
err = json.Unmarshal(body, &res)
141-
if err != nil {
142-
return nil, err
143-
}
144-
145-
if res.Error != nil {
146-
return nil, fmt.Errorf("json error %d: %s", res.Error.Code,
147-
res.Error.Message)
148-
}
149-
150-
data, err := hex.DecodeString(res.Result.Data)
151-
if err != nil {
152-
return nil, err
153-
}
154-
if len(data) != 192 {
155-
return nil, fmt.Errorf("wrong data length: got %d, expected 192",
156-
len(data))
157-
}
158-
target, err := hex.DecodeString(res.Result.Target)
159-
if err != nil {
160-
return nil, err
161-
}
162-
if len(target) != 32 {
163-
return nil, fmt.Errorf("wrong target length: got %d, expected 32",
164-
len(target))
165-
}
166-
167-
// The bigTarget difficulty is provided in little endian, but big integers
168-
// expect big endian, so reverse it accordingly.
169-
bigTarget := new(big.Int).SetBytes(util.Reverse(target))
170-
171-
var workData [192]byte
172-
copy(workData[:], data)
173-
174-
const isGetWork = true
175-
timestamp := binary.LittleEndian.Uint32(workData[128+4*work.TimestampWord:])
176-
w := work.NewWork(workData, bigTarget, timestamp, uint32(time.Now().Unix()),
177-
isGetWork)
178-
179-
w.Target = bigTarget
180-
181-
return w, nil
182-
}
183-
18413
// GetPoolWork gets work from a stratum enabled pool.
18514
func GetPoolWork(pool *stratum.Stratum) (*work.Work, error) {
18615
// Get Next work for stratum and mark it as used.
@@ -212,65 +41,6 @@ func GetPoolWork(pool *stratum.Stratum) (*work.Work, error) {
21241
return nil, fmt.Errorf("no work available")
21342
}
21443

215-
// GetWork makes a getwork RPC call and returns the result (data and target).
216-
func GetWorkSubmit(data []byte) (bool, error) {
217-
// Generate a request to the configured RPC server.
218-
protocol := "http"
219-
if !cfg.NoTLS {
220-
protocol = "https"
221-
}
222-
url := protocol + "://" + cfg.RPCServer
223-
hexData := hex.EncodeToString(data)
224-
jsonStr := []byte(`{"jsonrpc": "2.0", "method": "getwork", "params": ["` +
225-
hexData + `"], "id": 1}`)
226-
bodyBuff := bytes.NewBuffer(jsonStr)
227-
httpRequest, err := http.NewRequest("POST", url, bodyBuff)
228-
if err != nil {
229-
return false, err
230-
}
231-
httpRequest.Close = true
232-
httpRequest.Header.Set("Content-Type", "application/json")
233-
234-
// Configure basic access authorization.
235-
httpRequest.SetBasicAuth(cfg.RPCUser, cfg.RPCPassword)
236-
237-
// Create the new HTTP client that is configured according to the user-
238-
// specified options and submit the request.
239-
httpClient, err := newHTTPClient(cfg)
240-
if err != nil {
241-
return false, err
242-
}
243-
httpResponse, err := httpClient.Do(httpRequest)
244-
if err != nil {
245-
return false, err
246-
}
247-
248-
body, err := io.ReadAll(httpResponse.Body)
249-
httpResponse.Body.Close()
250-
if err != nil {
251-
err = fmt.Errorf("error reading json reply: %w", err)
252-
return false, err
253-
}
254-
255-
if httpResponse.Status != "200 OK" {
256-
return false, fmt.Errorf("error calling getwork (%s): %s",
257-
httpResponse.Status, body)
258-
}
259-
260-
var res getWorkSubmitResponseJson
261-
err = json.Unmarshal(body, &res)
262-
if err != nil {
263-
return false, err
264-
}
265-
266-
if res.Error != nil {
267-
return false, fmt.Errorf("json error %d: %s", res.Error.Code,
268-
res.Error.Message)
269-
}
270-
271-
return res.Result, nil
272-
}
273-
27444
// GetPoolWorkSubmit sends the result to the stratum enabled pool.
27545
func GetPoolWorkSubmit(data []byte, pool *stratum.Stratum) (bool, error) {
27646
pool.Lock()

go.mod

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ require (
88
github.com/decred/dcrd/blockchain/standalone/v2 v2.2.0
99
github.com/decred/dcrd/chaincfg/chainhash v1.0.4
1010
github.com/decred/dcrd/chaincfg/v3 v3.2.0
11-
github.com/decred/dcrd/crypto/blake256 v1.0.1
1211
github.com/decred/dcrd/dcrutil/v4 v4.0.1
12+
github.com/decred/dcrd/rpcclient/v8 v8.0.0
1313
github.com/decred/dcrd/wire v1.6.0
1414
github.com/decred/go-socks v1.1.0
1515
github.com/decred/slog v1.2.0
@@ -21,11 +21,18 @@ require (
2121
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 // indirect
2222
github.com/dchest/siphash v1.2.3 // indirect
2323
github.com/decred/base58 v1.0.5 // indirect
24+
github.com/decred/dcrd/blockchain/stake/v5 v5.0.0 // indirect
25+
github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect
2426
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
27+
github.com/decred/dcrd/database/v3 v3.0.1 // indirect
2528
github.com/decred/dcrd/dcrec v1.0.1 // indirect
2629
github.com/decred/dcrd/dcrec/edwards/v2 v2.0.3 // indirect
2730
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
31+
github.com/decred/dcrd/dcrjson/v4 v4.0.1 // indirect
32+
github.com/decred/dcrd/gcs/v4 v4.0.0 // indirect
33+
github.com/decred/dcrd/rpc/jsonrpc/types/v4 v4.0.0 // indirect
2834
github.com/decred/dcrd/txscript/v4 v4.1.0 // indirect
35+
github.com/gorilla/websocket v1.4.2 // indirect
2936
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
3037
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4 // indirect
3138
lukechampine.com/blake3 v1.2.1 // indirect

go.sum

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA=
88
github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc=
99
github.com/decred/base58 v1.0.5 h1:hwcieUM3pfPnE/6p3J100zoRfGkQxBulZHo7GZfOqic=
1010
github.com/decred/base58 v1.0.5/go.mod h1:s/8lukEHFA6bUQQb/v3rjUySJ2hu+RioCzLukAVkrfw=
11+
github.com/decred/dcrd/blockchain/stake/v5 v5.0.0 h1:WyxS8zMvTMpC5qYC9uJY+UzuV/x9ko4z20qBtH5Hzzs=
12+
github.com/decred/dcrd/blockchain/stake/v5 v5.0.0/go.mod h1:5sSjMq9THpnrLkW0SjEqIBIo8qq2nXzc+m7k9oFVVmY=
1113
github.com/decred/dcrd/blockchain/standalone/v2 v2.2.0 h1:v3yfo66axjr3oLihct+5tLEeM9YUzvK3i/6e2Im6RO0=
1214
github.com/decred/dcrd/blockchain/standalone/v2 v2.2.0/go.mod h1:JsOpl2nHhW2D2bWMEtbMuAE+mIU/Pdd1i1pmYR+2RYI=
1315
github.com/decred/dcrd/chaincfg/chainhash v1.0.4 h1:zRCv6tdncLfLTKYqu7hrXvs7hW+8FO/NvwoFvGsrluU=
@@ -18,14 +20,24 @@ github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5il
1820
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
1921
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
2022
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
23+
github.com/decred/dcrd/database/v3 v3.0.1 h1:oaklASAsUBwDoRgaS961WYqecFMZNhI1k+BmGgeW7/U=
24+
github.com/decred/dcrd/database/v3 v3.0.1/go.mod h1:IErr/Z62pFLoPZTMPGxedbcIuseGk0w3dszP3AFbXyw=
2125
github.com/decred/dcrd/dcrec v1.0.1 h1:gDzlndw0zYxM5BlaV17d7ZJV6vhRe9njPBFeg4Db2UY=
2226
github.com/decred/dcrd/dcrec v1.0.1/go.mod h1:CO+EJd8eHFb8WHa84C7ZBkXsNUIywaTHb+UAuI5uo6o=
2327
github.com/decred/dcrd/dcrec/edwards/v2 v2.0.3 h1:l/lhv2aJCUignzls81+wvga0TFlyoZx8QxRMQgXpZik=
2428
github.com/decred/dcrd/dcrec/edwards/v2 v2.0.3/go.mod h1:AKpV6+wZ2MfPRJnTbQ6NPgWrKzbe9RCIlCF/FKzMtM8=
2529
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
2630
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
31+
github.com/decred/dcrd/dcrjson/v4 v4.0.1 h1:vyQuB1miwGqbCVNm8P6br3V65WQ6wyrh0LycMkvaBBg=
32+
github.com/decred/dcrd/dcrjson/v4 v4.0.1/go.mod h1:2qVikafVF9/X3PngQVmqkbUbyAl32uik0k/kydgtqMc=
2733
github.com/decred/dcrd/dcrutil/v4 v4.0.1 h1:E+d2TNbpOj0f1L9RqkZkEm1QolFjajvkzxWC5WOPf1s=
2834
github.com/decred/dcrd/dcrutil/v4 v4.0.1/go.mod h1:7EXyHYj8FEqY+WzMuRkF0nh32ueLqhutZDoW4eQ+KRc=
35+
github.com/decred/dcrd/gcs/v4 v4.0.0 h1:bet+Ax1ZFUqn2M0g1uotm0b8F6BZ9MmblViyJ088E8k=
36+
github.com/decred/dcrd/gcs/v4 v4.0.0/go.mod h1:9z+EBagzpEdAumwS09vf/hiGaR8XhNmsBgaVq6u7/NI=
37+
github.com/decred/dcrd/rpc/jsonrpc/types/v4 v4.0.0 h1:4YUKsWKrKlkhVMYGRB6G0XI6QfwUnwEH18eoEbM1/+M=
38+
github.com/decred/dcrd/rpc/jsonrpc/types/v4 v4.0.0/go.mod h1:dDHO7ivrPAhZjFD3LoOJN/kdq5gi0sxie6zCsWHAiUo=
39+
github.com/decred/dcrd/rpcclient/v8 v8.0.0 h1:O4B5d+8e2OjbeFW+c1XcZNQzyp++04ArWhXgYrsURus=
40+
github.com/decred/dcrd/rpcclient/v8 v8.0.0/go.mod h1:gx4+DI5apuOEeLwPBJFlMoj3GFWq1I7/X8XCQmMTi8Q=
2941
github.com/decred/dcrd/txscript/v4 v4.1.0 h1:uEdcibIOl6BuWj3AqmXZ9xIK/qbo6lHY9aNk29FtkrU=
3042
github.com/decred/dcrd/txscript/v4 v4.1.0/go.mod h1:OVguPtPc4YMkgssxzP8B6XEMf/J3MB6S1JKpxgGQqi0=
3143
github.com/decred/dcrd/wire v1.6.0 h1:YOGwPHk4nzGr6OIwUGb8crJYWDiVLpuMxfDBCCF7s/o=
@@ -34,12 +46,16 @@ github.com/decred/go-socks v1.1.0 h1:dnENcc0KIqQo3HSXdgboXAHgqsCIutkqq6ntQjYtm2U
3446
github.com/decred/go-socks v1.1.0/go.mod h1:sDhHqkZH0X4JjSa02oYOGhcGHYp12FsY1jQ/meV8md0=
3547
github.com/decred/slog v1.2.0 h1:soHAxV52B54Di3WtKLfPum9OFfWqwtf/ygf9njdfnPM=
3648
github.com/decred/slog v1.2.0/go.mod h1:kVXlGnt6DHy2fV5OjSeuvCJ0OmlmTF6LFpEPMu/fOY0=
49+
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
50+
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
51+
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
3752
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
3853
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
3954
github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI=
4055
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
4156
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
4257
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
58+
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
4359
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4 h1:EZ2mChiOa8udjfp6rRmswTbtZN/QzUQp4ptM4rnjHvc=
4460
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
4561
lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=

main.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,15 @@ func gominerMain() error {
7575
}()
7676
}
7777

78-
m, err := NewMiner()
78+
ctx := shutdownListener()
79+
m, err := NewMiner(ctx)
7980
if err != nil {
8081
mainLog.Criticalf("Error initializing miner: %v", err)
8182
return err
8283
}
83-
8484
if len(cfg.APIListeners) != 0 {
8585
go RunMonitor(m)
8686
}
87-
88-
ctx := shutdownListener()
89-
9087
m.Run(ctx)
9188

9289
return nil

0 commit comments

Comments
 (0)