github.com/lbryio/lbcd@v0.22.119/rpcclient/mining.go (about) 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/lbryio/lbcd/btcjson" 13 "github.com/lbryio/lbcd/chaincfg/chainhash" 14 btcutil "github.com/lbryio/lbcutil" 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 // FutureGenerateToAddressResult is a future promise to deliver the result of a 65 // GenerateToAddressResult RPC invocation (or an applicable error). 66 type FutureGenerateToAddressResult chan *Response 67 68 // Receive waits for the Response promised by the future and returns the hashes of 69 // of the generated blocks. 70 func (f FutureGenerateToAddressResult) Receive() ([]*chainhash.Hash, error) { 71 res, err := ReceiveFuture(f) 72 if err != nil { 73 return nil, err 74 } 75 76 // Unmarshal result as a list of strings. 77 var result []string 78 err = json.Unmarshal(res, &result) 79 if err != nil { 80 return nil, err 81 } 82 83 // Convert each block hash to a chainhash.Hash and store a pointer to 84 // each. 85 convertedResult := make([]*chainhash.Hash, len(result)) 86 for i, hashString := range result { 87 convertedResult[i], err = chainhash.NewHashFromStr(hashString) 88 if err != nil { 89 return nil, err 90 } 91 } 92 93 return convertedResult, nil 94 } 95 96 // GenerateToAddressAsync returns an instance of a type that can be used to get 97 // the result of the RPC at some future time by invoking the Receive function on 98 // the returned instance. 99 // 100 // See GenerateToAddress for the blocking version and more details. 101 func (c *Client) GenerateToAddressAsync(numBlocks int64, address btcutil.Address, maxTries *int64) FutureGenerateToAddressResult { 102 cmd := btcjson.NewGenerateToAddressCmd(numBlocks, address.EncodeAddress(), maxTries) 103 return c.SendCmd(cmd) 104 } 105 106 // GenerateToAddress generates numBlocks blocks to the given address and returns their hashes. 107 func (c *Client) GenerateToAddress(numBlocks int64, address btcutil.Address, maxTries *int64) ([]*chainhash.Hash, error) { 108 return c.GenerateToAddressAsync(numBlocks, address, maxTries).Receive() 109 } 110 111 // FutureGetGenerateResult is a future promise to deliver the result of a 112 // GetGenerateAsync RPC invocation (or an applicable error). 113 type FutureGetGenerateResult chan *Response 114 115 // Receive waits for the Response promised by the future and returns true if the 116 // server is set to mine, otherwise false. 117 func (r FutureGetGenerateResult) Receive() (bool, error) { 118 res, err := ReceiveFuture(r) 119 if err != nil { 120 return false, err 121 } 122 123 // Unmarshal result as a boolean. 124 var result bool 125 err = json.Unmarshal(res, &result) 126 if err != nil { 127 return false, err 128 } 129 130 return result, nil 131 } 132 133 // GetGenerateAsync returns an instance of a type that can be used to get 134 // the result of the RPC at some future time by invoking the Receive function on 135 // the returned instance. 136 // 137 // See GetGenerate for the blocking version and more details. 138 func (c *Client) GetGenerateAsync() FutureGetGenerateResult { 139 cmd := btcjson.NewGetGenerateCmd() 140 return c.SendCmd(cmd) 141 } 142 143 // GetGenerate returns true if the server is set to mine, otherwise false. 144 func (c *Client) GetGenerate() (bool, error) { 145 return c.GetGenerateAsync().Receive() 146 } 147 148 // FutureSetGenerateResult is a future promise to deliver the result of a 149 // SetGenerateAsync RPC invocation (or an applicable error). 150 type FutureSetGenerateResult chan *Response 151 152 // Receive waits for the Response promised by the future and returns an error if 153 // any occurred when setting the server to generate coins (mine) or not. 154 func (r FutureSetGenerateResult) Receive() error { 155 _, err := ReceiveFuture(r) 156 return err 157 } 158 159 // SetGenerateAsync returns an instance of a type that can be used to get the 160 // result of the RPC at some future time by invoking the Receive function on the 161 // returned instance. 162 // 163 // See SetGenerate for the blocking version and more details. 164 func (c *Client) SetGenerateAsync(enable bool, numCPUs int) FutureSetGenerateResult { 165 cmd := btcjson.NewSetGenerateCmd(enable, &numCPUs) 166 return c.SendCmd(cmd) 167 } 168 169 // SetGenerate sets the server to generate coins (mine) or not. 170 func (c *Client) SetGenerate(enable bool, numCPUs int) error { 171 return c.SetGenerateAsync(enable, numCPUs).Receive() 172 } 173 174 // FutureGetHashesPerSecResult is a future promise to deliver the result of a 175 // GetHashesPerSecAsync RPC invocation (or an applicable error). 176 type FutureGetHashesPerSecResult chan *Response 177 178 // Receive waits for the Response promised by the future and returns a recent 179 // hashes per second performance measurement while generating coins (mining). 180 // Zero is returned if the server is not mining. 181 func (r FutureGetHashesPerSecResult) Receive() (int64, error) { 182 res, err := ReceiveFuture(r) 183 if err != nil { 184 return -1, err 185 } 186 187 // Unmarshal result as an int64. 188 var result int64 189 err = json.Unmarshal(res, &result) 190 if err != nil { 191 return 0, err 192 } 193 194 return result, nil 195 } 196 197 // GetHashesPerSecAsync returns an instance of a type that can be used to get 198 // the result of the RPC at some future time by invoking the Receive function on 199 // the returned instance. 200 // 201 // See GetHashesPerSec for the blocking version and more details. 202 func (c *Client) GetHashesPerSecAsync() FutureGetHashesPerSecResult { 203 cmd := btcjson.NewGetHashesPerSecCmd() 204 return c.SendCmd(cmd) 205 } 206 207 // GetHashesPerSec returns a recent hashes per second performance measurement 208 // while generating coins (mining). Zero is returned if the server is not 209 // mining. 210 func (c *Client) GetHashesPerSec() (int64, error) { 211 return c.GetHashesPerSecAsync().Receive() 212 } 213 214 // FutureGetMiningInfoResult is a future promise to deliver the result of a 215 // GetMiningInfoAsync RPC invocation (or an applicable error). 216 type FutureGetMiningInfoResult chan *Response 217 218 // Receive waits for the Response promised by the future and returns the mining 219 // information. 220 func (r FutureGetMiningInfoResult) Receive() (*btcjson.GetMiningInfoResult, error) { 221 res, err := ReceiveFuture(r) 222 if err != nil { 223 return nil, err 224 } 225 226 // Unmarshal result as a getmininginfo result object. 227 var infoResult btcjson.GetMiningInfoResult 228 err = json.Unmarshal(res, &infoResult) 229 if err != nil { 230 return nil, err 231 } 232 233 return &infoResult, nil 234 } 235 236 // GetMiningInfoAsync returns an instance of a type that can be used to get 237 // the result of the RPC at some future time by invoking the Receive function on 238 // the returned instance. 239 // 240 // See GetMiningInfo for the blocking version and more details. 241 func (c *Client) GetMiningInfoAsync() FutureGetMiningInfoResult { 242 cmd := btcjson.NewGetMiningInfoCmd() 243 return c.SendCmd(cmd) 244 } 245 246 // GetMiningInfo returns mining information. 247 func (c *Client) GetMiningInfo() (*btcjson.GetMiningInfoResult, error) { 248 return c.GetMiningInfoAsync().Receive() 249 } 250 251 // FutureGetNetworkHashPS is a future promise to deliver the result of a 252 // GetNetworkHashPSAsync RPC invocation (or an applicable error). 253 type FutureGetNetworkHashPS chan *Response 254 255 // Receive waits for the Response promised by the future and returns the 256 // estimated network hashes per second for the block heights provided by the 257 // parameters. 258 func (r FutureGetNetworkHashPS) Receive() (int64, error) { 259 res, err := ReceiveFuture(r) 260 if err != nil { 261 return -1, err 262 } 263 264 // Unmarshal result as an int64. 265 var result int64 266 err = json.Unmarshal(res, &result) 267 if err != nil { 268 return 0, err 269 } 270 271 return result, nil 272 } 273 274 // GetNetworkHashPSAsync returns an instance of a type that can be used to get 275 // the result of the RPC at some future time by invoking the Receive function on 276 // the returned instance. 277 // 278 // See GetNetworkHashPS for the blocking version and more details. 279 func (c *Client) GetNetworkHashPSAsync() FutureGetNetworkHashPS { 280 cmd := btcjson.NewGetNetworkHashPSCmd(nil, nil) 281 return c.SendCmd(cmd) 282 } 283 284 // GetNetworkHashPS returns the estimated network hashes per second using the 285 // default number of blocks and the most recent block height. 286 // 287 // See GetNetworkHashPS2 to override the number of blocks to use and 288 // GetNetworkHashPS3 to override the height at which to calculate the estimate. 289 func (c *Client) GetNetworkHashPS() (int64, error) { 290 return c.GetNetworkHashPSAsync().Receive() 291 } 292 293 // GetNetworkHashPS2Async returns an instance of a type that can be used to get 294 // the result of the RPC at some future time by invoking the Receive function on 295 // the returned instance. 296 // 297 // See GetNetworkHashPS2 for the blocking version and more details. 298 func (c *Client) GetNetworkHashPS2Async(blocks int) FutureGetNetworkHashPS { 299 cmd := btcjson.NewGetNetworkHashPSCmd(&blocks, nil) 300 return c.SendCmd(cmd) 301 } 302 303 // GetNetworkHashPS2 returns the estimated network hashes per second for the 304 // specified previous number of blocks working backwards from the most recent 305 // block height. The blocks parameter can also be -1 in which case the number 306 // of blocks since the last difficulty change will be used. 307 // 308 // See GetNetworkHashPS to use defaults and GetNetworkHashPS3 to override the 309 // height at which to calculate the estimate. 310 func (c *Client) GetNetworkHashPS2(blocks int) (int64, error) { 311 return c.GetNetworkHashPS2Async(blocks).Receive() 312 } 313 314 // GetNetworkHashPS3Async returns an instance of a type that can be used to get 315 // the result of the RPC at some future time by invoking the Receive function on 316 // the returned instance. 317 // 318 // See GetNetworkHashPS3 for the blocking version and more details. 319 func (c *Client) GetNetworkHashPS3Async(blocks, height int) FutureGetNetworkHashPS { 320 cmd := btcjson.NewGetNetworkHashPSCmd(&blocks, &height) 321 return c.SendCmd(cmd) 322 } 323 324 // GetNetworkHashPS3 returns the estimated network hashes per second for the 325 // specified previous number of blocks working backwards from the specified 326 // block height. The blocks parameter can also be -1 in which case the number 327 // of blocks since the last difficulty change will be used. 328 // 329 // See GetNetworkHashPS and GetNetworkHashPS2 to use defaults. 330 func (c *Client) GetNetworkHashPS3(blocks, height int) (int64, error) { 331 return c.GetNetworkHashPS3Async(blocks, height).Receive() 332 } 333 334 // FutureGetWork is a future promise to deliver the result of a 335 // GetWorkAsync RPC invocation (or an applicable error). 336 type FutureGetWork chan *Response 337 338 // Receive waits for the Response promised by the future and returns the hash 339 // data to work on. 340 func (r FutureGetWork) Receive() (*btcjson.GetWorkResult, error) { 341 res, err := ReceiveFuture(r) 342 if err != nil { 343 return nil, err 344 } 345 346 // Unmarshal result as a getwork result object. 347 var result btcjson.GetWorkResult 348 err = json.Unmarshal(res, &result) 349 if err != nil { 350 return nil, err 351 } 352 353 return &result, nil 354 } 355 356 // GetWorkAsync returns an instance of a type that can be used to get the result 357 // of the RPC at some future time by invoking the Receive function on the 358 // returned instance. 359 // 360 // See GetWork for the blocking version and more details. 361 func (c *Client) GetWorkAsync() FutureGetWork { 362 cmd := btcjson.NewGetWorkCmd(nil) 363 return c.SendCmd(cmd) 364 } 365 366 // GetWork returns hash data to work on. 367 // 368 // See GetWorkSubmit to submit the found solution. 369 func (c *Client) GetWork() (*btcjson.GetWorkResult, error) { 370 return c.GetWorkAsync().Receive() 371 } 372 373 // FutureGetWorkSubmit is a future promise to deliver the result of a 374 // GetWorkSubmitAsync RPC invocation (or an applicable error). 375 type FutureGetWorkSubmit chan *Response 376 377 // Receive waits for the Response promised by the future and returns whether 378 // or not the submitted block header was accepted. 379 func (r FutureGetWorkSubmit) Receive() (bool, error) { 380 res, err := ReceiveFuture(r) 381 if err != nil { 382 return false, err 383 } 384 385 // Unmarshal result as a boolean. 386 var accepted bool 387 err = json.Unmarshal(res, &accepted) 388 if err != nil { 389 return false, err 390 } 391 392 return accepted, nil 393 } 394 395 // GetWorkSubmitAsync returns an instance of a type that can be used to get the 396 // result of the RPC at some future time by invoking the Receive function on the 397 // returned instance. 398 // 399 // See GetWorkSubmit for the blocking version and more details. 400 func (c *Client) GetWorkSubmitAsync(data string) FutureGetWorkSubmit { 401 cmd := btcjson.NewGetWorkCmd(&data) 402 return c.SendCmd(cmd) 403 } 404 405 // GetWorkSubmit submits a block header which is a solution to previously 406 // requested data and returns whether or not the solution was accepted. 407 // 408 // See GetWork to request data to work on. 409 func (c *Client) GetWorkSubmit(data string) (bool, error) { 410 return c.GetWorkSubmitAsync(data).Receive() 411 } 412 413 // FutureSubmitBlockResult is a future promise to deliver the result of a 414 // SubmitBlockAsync RPC invocation (or an applicable error). 415 type FutureSubmitBlockResult chan *Response 416 417 // Receive waits for the Response promised by the future and returns an error if 418 // any occurred when submitting the block. 419 func (r FutureSubmitBlockResult) Receive() error { 420 res, err := ReceiveFuture(r) 421 if err != nil { 422 return err 423 } 424 425 if string(res) != "null" { 426 var result string 427 err = json.Unmarshal(res, &result) 428 if err != nil { 429 return err 430 } 431 432 return errors.New(result) 433 } 434 435 return nil 436 437 } 438 439 // SubmitBlockAsync returns an instance of a type that can be used to get the 440 // result of the RPC at some future time by invoking the Receive function on the 441 // returned instance. 442 // 443 // See SubmitBlock for the blocking version and more details. 444 func (c *Client) SubmitBlockAsync(block *btcutil.Block, options *btcjson.SubmitBlockOptions) FutureSubmitBlockResult { 445 blockHex := "" 446 if block != nil { 447 blockBytes, err := block.Bytes() 448 if err != nil { 449 return newFutureError(err) 450 } 451 452 blockHex = hex.EncodeToString(blockBytes) 453 } 454 455 cmd := btcjson.NewSubmitBlockCmd(blockHex, options) 456 return c.SendCmd(cmd) 457 } 458 459 // SubmitBlock attempts to submit a new block into the bitcoin network. 460 func (c *Client) SubmitBlock(block *btcutil.Block, options *btcjson.SubmitBlockOptions) error { 461 return c.SubmitBlockAsync(block, options).Receive() 462 } 463 464 // FutureGetBlockTemplateResponse is a future promise to deliver the result of a 465 // GetBlockTemplateAsync RPC invocation (or an applicable error). 466 type FutureGetBlockTemplateResponse chan *Response 467 468 // Receive waits for the Response promised by the future and returns an error if 469 // any occurred when retrieving the block template. 470 func (r FutureGetBlockTemplateResponse) Receive() (*btcjson.GetBlockTemplateResult, error) { 471 res, err := ReceiveFuture(r) 472 if err != nil { 473 return nil, err 474 } 475 476 // Unmarshal result as a getwork result object. 477 var result btcjson.GetBlockTemplateResult 478 err = json.Unmarshal(res, &result) 479 if err != nil { 480 return nil, err 481 } 482 483 return &result, nil 484 } 485 486 // GetBlockTemplateAsync returns an instance of a type that can be used to get the 487 // result of the RPC at some future time by invoking the Receive function on the 488 // returned instance. 489 // 490 // See GetBlockTemplate for the blocking version and more details. 491 func (c *Client) GetBlockTemplateAsync(req *btcjson.TemplateRequest) FutureGetBlockTemplateResponse { 492 cmd := btcjson.NewGetBlockTemplateCmd(req) 493 return c.SendCmd(cmd) 494 } 495 496 // GetBlockTemplate returns a new block template for mining. 497 func (c *Client) GetBlockTemplate(req *btcjson.TemplateRequest) (*btcjson.GetBlockTemplateResult, error) { 498 return c.GetBlockTemplateAsync(req).Receive() 499 }