OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / rpcclient / mining.go
1 // Copyright (c) 2014-2017 The btcsuite developers
2 // Use of this source code is governed by an ISC
3 // license that can be found in the LICENSE file.
4
5 package rpcclient
6
7 import (
8         "encoding/hex"
9         "encoding/json"
10         "errors"
11
12         "github.com/btcsuite/btcd/btcjson"
13         "github.com/btcsuite/btcd/chaincfg/chainhash"
14         "github.com/btcsuite/btcutil"
15 )
16
17 // FutureGenerateResult is a future promise to deliver the result of a
18 // GenerateAsync RPC invocation (or an applicable error).
19 type FutureGenerateResult chan *response
20
21 // Receive waits for the response promised by the future and returns a list of
22 // block hashes generated by the call.
23 func (r FutureGenerateResult) Receive() ([]*chainhash.Hash, error) {
24         res, err := receiveFuture(r)
25         if err != nil {
26                 return nil, err
27         }
28
29         // Unmarshal result as a list of strings.
30         var result []string
31         err = json.Unmarshal(res, &result)
32         if err != nil {
33                 return nil, err
34         }
35
36         // Convert each block hash to a chainhash.Hash and store a pointer to
37         // each.
38         convertedResult := make([]*chainhash.Hash, len(result))
39         for i, hashString := range result {
40                 convertedResult[i], err = chainhash.NewHashFromStr(hashString)
41                 if err != nil {
42                         return nil, err
43                 }
44         }
45
46         return convertedResult, nil
47 }
48
49 // GenerateAsync returns an instance of a type that can be used to get
50 // the result of the RPC at some future time by invoking the Receive function on
51 // the returned instance.
52 //
53 // See Generate for the blocking version and more details.
54 func (c *Client) GenerateAsync(numBlocks uint32) FutureGenerateResult {
55         cmd := btcjson.NewGenerateCmd(numBlocks)
56         return c.sendCmd(cmd)
57 }
58
59 // Generate generates numBlocks blocks and returns their hashes.
60 func (c *Client) Generate(numBlocks uint32) ([]*chainhash.Hash, error) {
61         return c.GenerateAsync(numBlocks).Receive()
62 }
63
64 // FutureGetGenerateResult is a future promise to deliver the result of a
65 // GetGenerateAsync RPC invocation (or an applicable error).
66 type FutureGetGenerateResult chan *response
67
68 // Receive waits for the response promised by the future and returns true if the
69 // server is set to mine, otherwise false.
70 func (r FutureGetGenerateResult) Receive() (bool, error) {
71         res, err := receiveFuture(r)
72         if err != nil {
73                 return false, err
74         }
75
76         // Unmarshal result as a boolean.
77         var result bool
78         err = json.Unmarshal(res, &result)
79         if err != nil {
80                 return false, err
81         }
82
83         return result, nil
84 }
85
86 // GetGenerateAsync returns an instance of a type that can be used to get
87 // the result of the RPC at some future time by invoking the Receive function on
88 // the returned instance.
89 //
90 // See GetGenerate for the blocking version and more details.
91 func (c *Client) GetGenerateAsync() FutureGetGenerateResult {
92         cmd := btcjson.NewGetGenerateCmd()
93         return c.sendCmd(cmd)
94 }
95
96 // GetGenerate returns true if the server is set to mine, otherwise false.
97 func (c *Client) GetGenerate() (bool, error) {
98         return c.GetGenerateAsync().Receive()
99 }
100
101 // FutureSetGenerateResult is a future promise to deliver the result of a
102 // SetGenerateAsync RPC invocation (or an applicable error).
103 type FutureSetGenerateResult chan *response
104
105 // Receive waits for the response promised by the future and returns an error if
106 // any occurred when setting the server to generate coins (mine) or not.
107 func (r FutureSetGenerateResult) Receive() error {
108         _, err := receiveFuture(r)
109         return err
110 }
111
112 // SetGenerateAsync returns an instance of a type that can be used to get the
113 // result of the RPC at some future time by invoking the Receive function on the
114 // returned instance.
115 //
116 // See SetGenerate for the blocking version and more details.
117 func (c *Client) SetGenerateAsync(enable bool, numCPUs int) FutureSetGenerateResult {
118         cmd := btcjson.NewSetGenerateCmd(enable, &numCPUs)
119         return c.sendCmd(cmd)
120 }
121
122 // SetGenerate sets the server to generate coins (mine) or not.
123 func (c *Client) SetGenerate(enable bool, numCPUs int) error {
124         return c.SetGenerateAsync(enable, numCPUs).Receive()
125 }
126
127 // FutureGetHashesPerSecResult is a future promise to deliver the result of a
128 // GetHashesPerSecAsync RPC invocation (or an applicable error).
129 type FutureGetHashesPerSecResult chan *response
130
131 // Receive waits for the response promised by the future and returns a recent
132 // hashes per second performance measurement while generating coins (mining).
133 // Zero is returned if the server is not mining.
134 func (r FutureGetHashesPerSecResult) Receive() (int64, error) {
135         res, err := receiveFuture(r)
136         if err != nil {
137                 return -1, err
138         }
139
140         // Unmarshal result as an int64.
141         var result int64
142         err = json.Unmarshal(res, &result)
143         if err != nil {
144                 return 0, err
145         }
146
147         return result, nil
148 }
149
150 // GetHashesPerSecAsync returns an instance of a type that can be used to get
151 // the result of the RPC at some future time by invoking the Receive function on
152 // the returned instance.
153 //
154 // See GetHashesPerSec for the blocking version and more details.
155 func (c *Client) GetHashesPerSecAsync() FutureGetHashesPerSecResult {
156         cmd := btcjson.NewGetHashesPerSecCmd()
157         return c.sendCmd(cmd)
158 }
159
160 // GetHashesPerSec returns a recent hashes per second performance measurement
161 // while generating coins (mining).  Zero is returned if the server is not
162 // mining.
163 func (c *Client) GetHashesPerSec() (int64, error) {
164         return c.GetHashesPerSecAsync().Receive()
165 }
166
167 // FutureGetMiningInfoResult is a future promise to deliver the result of a
168 // GetMiningInfoAsync RPC invocation (or an applicable error).
169 type FutureGetMiningInfoResult chan *response
170
171 // Receive waits for the response promised by the future and returns the mining
172 // information.
173 func (r FutureGetMiningInfoResult) Receive() (*btcjson.GetMiningInfoResult, error) {
174         res, err := receiveFuture(r)
175         if err != nil {
176                 return nil, err
177         }
178
179         // Unmarshal result as a getmininginfo result object.
180         var infoResult btcjson.GetMiningInfoResult
181         err = json.Unmarshal(res, &infoResult)
182         if err != nil {
183                 return nil, err
184         }
185
186         return &infoResult, nil
187 }
188
189 // GetMiningInfoAsync returns an instance of a type that can be used to get
190 // the result of the RPC at some future time by invoking the Receive function on
191 // the returned instance.
192 //
193 // See GetMiningInfo for the blocking version and more details.
194 func (c *Client) GetMiningInfoAsync() FutureGetMiningInfoResult {
195         cmd := btcjson.NewGetMiningInfoCmd()
196         return c.sendCmd(cmd)
197 }
198
199 // GetMiningInfo returns mining information.
200 func (c *Client) GetMiningInfo() (*btcjson.GetMiningInfoResult, error) {
201         return c.GetMiningInfoAsync().Receive()
202 }
203
204 // FutureGetNetworkHashPS is a future promise to deliver the result of a
205 // GetNetworkHashPSAsync RPC invocation (or an applicable error).
206 type FutureGetNetworkHashPS chan *response
207
208 // Receive waits for the response promised by the future and returns the
209 // estimated network hashes per second for the block heights provided by the
210 // parameters.
211 func (r FutureGetNetworkHashPS) Receive() (int64, error) {
212         res, err := receiveFuture(r)
213         if err != nil {
214                 return -1, err
215         }
216
217         // Unmarshal result as an int64.
218         var result int64
219         err = json.Unmarshal(res, &result)
220         if err != nil {
221                 return 0, err
222         }
223
224         return result, nil
225 }
226
227 // GetNetworkHashPSAsync returns an instance of a type that can be used to get
228 // the result of the RPC at some future time by invoking the Receive function on
229 // the returned instance.
230 //
231 // See GetNetworkHashPS for the blocking version and more details.
232 func (c *Client) GetNetworkHashPSAsync() FutureGetNetworkHashPS {
233         cmd := btcjson.NewGetNetworkHashPSCmd(nil, nil)
234         return c.sendCmd(cmd)
235 }
236
237 // GetNetworkHashPS returns the estimated network hashes per second using the
238 // default number of blocks and the most recent block height.
239 //
240 // See GetNetworkHashPS2 to override the number of blocks to use and
241 // GetNetworkHashPS3 to override the height at which to calculate the estimate.
242 func (c *Client) GetNetworkHashPS() (int64, error) {
243         return c.GetNetworkHashPSAsync().Receive()
244 }
245
246 // GetNetworkHashPS2Async returns an instance of a type that can be used to get
247 // the result of the RPC at some future time by invoking the Receive function on
248 // the returned instance.
249 //
250 // See GetNetworkHashPS2 for the blocking version and more details.
251 func (c *Client) GetNetworkHashPS2Async(blocks int) FutureGetNetworkHashPS {
252         cmd := btcjson.NewGetNetworkHashPSCmd(&blocks, nil)
253         return c.sendCmd(cmd)
254 }
255
256 // GetNetworkHashPS2 returns the estimated network hashes per second for the
257 // specified previous number of blocks working backwards from the most recent
258 // block height.  The blocks parameter can also be -1 in which case the number
259 // of blocks since the last difficulty change will be used.
260 //
261 // See GetNetworkHashPS to use defaults and GetNetworkHashPS3 to override the
262 // height at which to calculate the estimate.
263 func (c *Client) GetNetworkHashPS2(blocks int) (int64, error) {
264         return c.GetNetworkHashPS2Async(blocks).Receive()
265 }
266
267 // GetNetworkHashPS3Async returns an instance of a type that can be used to get
268 // the result of the RPC at some future time by invoking the Receive function on
269 // the returned instance.
270 //
271 // See GetNetworkHashPS3 for the blocking version and more details.
272 func (c *Client) GetNetworkHashPS3Async(blocks, height int) FutureGetNetworkHashPS {
273         cmd := btcjson.NewGetNetworkHashPSCmd(&blocks, &height)
274         return c.sendCmd(cmd)
275 }
276
277 // GetNetworkHashPS3 returns the estimated network hashes per second for the
278 // specified previous number of blocks working backwards from the specified
279 // block height.  The blocks parameter can also be -1 in which case the number
280 // of blocks since the last difficulty change will be used.
281 //
282 // See GetNetworkHashPS and GetNetworkHashPS2 to use defaults.
283 func (c *Client) GetNetworkHashPS3(blocks, height int) (int64, error) {
284         return c.GetNetworkHashPS3Async(blocks, height).Receive()
285 }
286
287 // FutureGetWork is a future promise to deliver the result of a
288 // GetWorkAsync RPC invocation (or an applicable error).
289 type FutureGetWork chan *response
290
291 // Receive waits for the response promised by the future and returns the hash
292 // data to work on.
293 func (r FutureGetWork) Receive() (*btcjson.GetWorkResult, error) {
294         res, err := receiveFuture(r)
295         if err != nil {
296                 return nil, err
297         }
298
299         // Unmarshal result as a getwork result object.
300         var result btcjson.GetWorkResult
301         err = json.Unmarshal(res, &result)
302         if err != nil {
303                 return nil, err
304         }
305
306         return &result, nil
307 }
308
309 // GetWorkAsync returns an instance of a type that can be used to get the result
310 // of the RPC at some future time by invoking the Receive function on the
311 // returned instance.
312 //
313 // See GetWork for the blocking version and more details.
314 func (c *Client) GetWorkAsync() FutureGetWork {
315         cmd := btcjson.NewGetWorkCmd(nil)
316         return c.sendCmd(cmd)
317 }
318
319 // GetWork returns hash data to work on.
320 //
321 // See GetWorkSubmit to submit the found solution.
322 func (c *Client) GetWork() (*btcjson.GetWorkResult, error) {
323         return c.GetWorkAsync().Receive()
324 }
325
326 // FutureGetWorkSubmit is a future promise to deliver the result of a
327 // GetWorkSubmitAsync RPC invocation (or an applicable error).
328 type FutureGetWorkSubmit chan *response
329
330 // Receive waits for the response promised by the future and returns whether
331 // or not the submitted block header was accepted.
332 func (r FutureGetWorkSubmit) Receive() (bool, error) {
333         res, err := receiveFuture(r)
334         if err != nil {
335                 return false, err
336         }
337
338         // Unmarshal result as a boolean.
339         var accepted bool
340         err = json.Unmarshal(res, &accepted)
341         if err != nil {
342                 return false, err
343         }
344
345         return accepted, nil
346 }
347
348 // GetWorkSubmitAsync returns an instance of a type that can be used to get the
349 // result of the RPC at some future time by invoking the Receive function on the
350 // returned instance.
351 //
352 // See GetWorkSubmit for the blocking version and more details.
353 func (c *Client) GetWorkSubmitAsync(data string) FutureGetWorkSubmit {
354         cmd := btcjson.NewGetWorkCmd(&data)
355         return c.sendCmd(cmd)
356 }
357
358 // GetWorkSubmit submits a block header which is a solution to previously
359 // requested data and returns whether or not the solution was accepted.
360 //
361 // See GetWork to request data to work on.
362 func (c *Client) GetWorkSubmit(data string) (bool, error) {
363         return c.GetWorkSubmitAsync(data).Receive()
364 }
365
366 // FutureSubmitBlockResult is a future promise to deliver the result of a
367 // SubmitBlockAsync RPC invocation (or an applicable error).
368 type FutureSubmitBlockResult chan *response
369
370 // Receive waits for the response promised by the future and returns an error if
371 // any occurred when submitting the block.
372 func (r FutureSubmitBlockResult) Receive() error {
373         res, err := receiveFuture(r)
374         if err != nil {
375                 return err
376         }
377
378         if string(res) != "null" {
379                 var result string
380                 err = json.Unmarshal(res, &result)
381                 if err != nil {
382                         return err
383                 }
384
385                 return errors.New(result)
386         }
387
388         return nil
389
390 }
391
392 // SubmitBlockAsync returns an instance of a type that can be used to get the
393 // result of the RPC at some future time by invoking the Receive function on the
394 // returned instance.
395 //
396 // See SubmitBlock for the blocking version and more details.
397 func (c *Client) SubmitBlockAsync(block *btcutil.Block, options *btcjson.SubmitBlockOptions) FutureSubmitBlockResult {
398         blockHex := ""
399         if block != nil {
400                 blockBytes, err := block.Bytes()
401                 if err != nil {
402                         return newFutureError(err)
403                 }
404
405                 blockHex = hex.EncodeToString(blockBytes)
406         }
407
408         cmd := btcjson.NewSubmitBlockCmd(blockHex, options)
409         return c.sendCmd(cmd)
410 }
411
412 // SubmitBlock attempts to submit a new block into the bitcoin network.
413 func (c *Client) SubmitBlock(block *btcutil.Block, options *btcjson.SubmitBlockOptions) error {
414         return c.SubmitBlockAsync(block, options).Receive()
415 }
416
417 // TODO(davec): Implement GetBlockTemplate