Skip to content

Commit

Permalink
Add getchaintxstats JSON-RPC client command
Browse files Browse the repository at this point in the history
Introduce Int32OrNil for feeding null parameter from command line.
This is useful for getchaintxstats to be able to define both params
while using the server-side calculated default value for the
first param.

Stopped panicking when providing null input from comand line to
array/slice/struct/map.
  • Loading branch information
lindlof committed Jun 10, 2020
1 parent 9f0179f commit 38656bd
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 0 deletions.
19 changes: 19 additions & 0 deletions btcjson/chainsvrcmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,24 @@ func NewGetChainTipsCmd() *GetChainTipsCmd {
return &GetChainTipsCmd{}
}

// GetChainTxStatsCmd defines the getchaintxstats JSON-RPC command.
type GetChainTxStatsCmd struct {
NBlocks *int32
BlockHash *string
}

// NewGetChainTxStatsCmd returns a new instance which can be used to issue a
// getchaintxstats JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetChainTxStatsCmd(nBlocks *int32, blockHash *string) *GetChainTxStatsCmd {
return &GetChainTxStatsCmd{
NBlocks: nBlocks,
BlockHash: blockHash,
}
}

// GetConnectionCountCmd defines the getconnectioncount JSON-RPC command.
type GetConnectionCountCmd struct{}

Expand Down Expand Up @@ -847,6 +865,7 @@ func init() {
MustRegisterCmd("getcfilter", (*GetCFilterCmd)(nil), flags)
MustRegisterCmd("getcfilterheader", (*GetCFilterHeaderCmd)(nil), flags)
MustRegisterCmd("getchaintips", (*GetChainTipsCmd)(nil), flags)
MustRegisterCmd("getchaintxstats", (*GetChainTxStatsCmd)(nil), flags)
MustRegisterCmd("getconnectioncount", (*GetConnectionCountCmd)(nil), flags)
MustRegisterCmd("getdifficulty", (*GetDifficultyCmd)(nil), flags)
MustRegisterCmd("getgenerate", (*GetGenerateCmd)(nil), flags)
Expand Down
38 changes: 38 additions & 0 deletions btcjson/chainsvrcmds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,44 @@ func TestChainSvrCmds(t *testing.T) {
marshalled: `{"jsonrpc":"1.0","method":"getchaintips","params":[],"id":1}`,
unmarshalled: &btcjson.GetChainTipsCmd{},
},
{
name: "getchaintxstats",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("getchaintxstats")
},
staticCmd: func() interface{} {
return btcjson.NewGetChainTxStatsCmd(nil, nil)
},
marshalled: `{"jsonrpc":"1.0","method":"getchaintxstats","params":[],"id":1}`,
unmarshalled: &btcjson.GetChainTxStatsCmd{},
},
{
name: "getchaintxstats optional nblocks",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("getchaintxstats", btcjson.Int32(1000))
},
staticCmd: func() interface{} {
return btcjson.NewGetChainTxStatsCmd(btcjson.Int32(1000), nil)
},
marshalled: `{"jsonrpc":"1.0","method":"getchaintxstats","params":[1000],"id":1}`,
unmarshalled: &btcjson.GetChainTxStatsCmd{
NBlocks: btcjson.Int32(1000),
},
},
{
name: "getchaintxstats optional nblocks and blockhash",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("getchaintxstats", btcjson.Int32(1000), btcjson.String("0000afaf"))
},
staticCmd: func() interface{} {
return btcjson.NewGetChainTxStatsCmd(btcjson.Int32(1000), btcjson.String("0000afaf"))
},
marshalled: `{"jsonrpc":"1.0","method":"getchaintxstats","params":[1000,"0000afaf"],"id":1}`,
unmarshalled: &btcjson.GetChainTxStatsCmd{
NBlocks: btcjson.Int32(1000),
BlockHash: btcjson.String("0000afaf"),
},
},
{
name: "getconnectioncount",
newCmd: func() (interface{}, error) {
Expand Down
12 changes: 12 additions & 0 deletions btcjson/chainsvrresults.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,18 @@ type GetBlockVerboseTxResult struct {
NextHash string `json:"nextblockhash,omitempty"`
}

// GetChainTxStatsResult models the data from the getchaintxstats command.
type GetChainTxStatsResult struct {
Time int64 `json:"time"`
TxCount int64 `json:"txcount"`
WindowFinalBlockHash string `json:"window_final_block_hash"`
WindowFinalBlockHeight int32 `json:"window_final_block_height"`
WindowBlockCount int32 `json:"window_block_count"`
WindowTxCount int32 `json:"window_tx_count"`
WindowInterval int32 `json:"window_interval"`
TxRate float64 `json:"txrate"`
}

// CreateMultiSigResult models the data returned from the createmultisig
// command.
type CreateMultiSigResult struct {
Expand Down
73 changes: 73 additions & 0 deletions rpcclient/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,79 @@ func (c *Client) GetBlockCount() (int64, error) {
return c.GetBlockCountAsync().Receive()
}

// FutureGetChainTxStatsResult is a future promise to deliver the result of a
// GetChainTxStatsAsync RPC invocation (or an applicable error).
type FutureGetChainTxStatsResult chan *response

// Receive waits for the response promised by the future and returns transaction statistics
func (r FutureGetChainTxStatsResult) Receive() (*btcjson.GetChainTxStatsResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}

var chainTxStats btcjson.GetChainTxStatsResult
err = json.Unmarshal(res, &chainTxStats)
if err != nil {
return nil, err
}

return &chainTxStats, nil
}

// GetChainTxStatsAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetChainTxStats for the blocking version and more details.
func (c *Client) GetChainTxStatsAsync() FutureGetChainTxStatsResult {
cmd := btcjson.NewGetChainTxStatsCmd(nil, nil)
return c.sendCmd(cmd)
}

// GetChainTxStatsNBlocksAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetChainTxStatsNBlocks for the blocking version and more details.
func (c *Client) GetChainTxStatsNBlocksAsync(nBlocks int32) FutureGetChainTxStatsResult {
cmd := btcjson.NewGetChainTxStatsCmd(&nBlocks, nil)
return c.sendCmd(cmd)
}

// GetChainTxStatsNBlocksBlockHashAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetChainTxStatsNBlocksBlockHash for the blocking version and more details.
func (c *Client) GetChainTxStatsNBlocksBlockHashAsync(nBlocks int32, blockHash chainhash.Hash) FutureGetChainTxStatsResult {
hash := blockHash.String()
cmd := btcjson.NewGetChainTxStatsCmd(&nBlocks, &hash)
return c.sendCmd(cmd)
}

// GetChainTxStats returns statistics about the total number and rate of transactions in the chain.
//
// Size of the window is one month and it ends at chain tip.
func (c *Client) GetChainTxStats() (*btcjson.GetChainTxStatsResult, error) {
return c.GetChainTxStatsAsync().Receive()
}

// GetChainTxStatsNBlock returns statistics about the total number and rate of transactions in the chain.
//
// The argument specifies size of the window in number of blocks. The window ends at chain tip.
func (c *Client) GetChainTxStatsNBlock(nBlocks int32) (*btcjson.GetChainTxStatsResult, error) {
return c.GetChainTxStatsNBlocksAsync(nBlocks).Receive()
}

// GetChainTxStatsNBlocksBlockHash returns statistics about the total number and rate of transactions in the chain.
//
// First argument specifies size of the window in number of blocks.
// Second argument is the hash of the block that ends the window.
func (c *Client) GetChainTxStatsNBlocksBlockHash(nBlocks int32, blockHash chainhash.Hash) (*btcjson.GetChainTxStatsResult, error) {
return c.GetChainTxStatsNBlocksBlockHashAsync(nBlocks, blockHash).Receive()
}

// FutureGetDifficultyResult is a future promise to deliver the result of a
// GetDifficultyAsync RPC invocation (or an applicable error).
type FutureGetDifficultyResult chan *response
Expand Down

0 comments on commit 38656bd

Please sign in to comment.