diff --git a/btcjson/chainsvrcmds.go b/btcjson/chainsvrcmds.go index 2f3069fd15..9932e439a5 100644 --- a/btcjson/chainsvrcmds.go +++ b/btcjson/chainsvrcmds.go @@ -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{} @@ -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) diff --git a/btcjson/chainsvrcmds_test.go b/btcjson/chainsvrcmds_test.go index 8f3fd455c5..5483e9a7f2 100644 --- a/btcjson/chainsvrcmds_test.go +++ b/btcjson/chainsvrcmds_test.go @@ -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) { diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index d076b74691..0c4e66bb99 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -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 { diff --git a/rpcclient/chain.go b/rpcclient/chain.go index 6e701b1c97..9f0c6c684d 100644 --- a/rpcclient/chain.go +++ b/rpcclient/chain.go @@ -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() +} + +// GetChainTxStatsNBlocks 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) GetChainTxStatsNBlocks(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