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  }