Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rpcclient: Add getblockfilter JSON-RPC client command #1579

Merged
merged 1 commit into from
Aug 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions btcjson/chainsvrcmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,33 @@ func NewGetBlockCountCmd() *GetBlockCountCmd {
return &GetBlockCountCmd{}
}

// FilterTypeName defines the type used in the getblockfilter JSON-RPC command for the
// filter type field.
type FilterTypeName string

const (
// FilterTypeBasic is the basic filter type defined in BIP0158.
FilterTypeBasic FilterTypeName = "basic"
)

// GetBlockFilterCmd defines the getblockfilter JSON-RPC command.
type GetBlockFilterCmd struct {
BlockHash string // The hash of the block
FilterType *FilterTypeName // The type name of the filter, default=basic
}

// NewGetBlockFilterCmd returns a new instance which can be used to issue a
// getblockfilter JSON-RPC command.
Comment on lines +181 to +182
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We generally add the following comment whenever there are optional arguments.

Suggested change
// NewGetBlockFilterCmd returns a new instance which can be used to issue a
// getblockfilter JSON-RPC command.
// NewGetBlockFilterCmd returns a new instance which can be used to issue a
// getblockfilter JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right on. Added these.

//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetBlockFilterCmd(blockHash string, filterType *FilterTypeName) *GetBlockFilterCmd {
return &GetBlockFilterCmd{
BlockHash: blockHash,
FilterType: filterType,
}
}

// GetBlockHashCmd defines the getblockhash JSON-RPC command.
type GetBlockHashCmd struct {
Index int64
Expand Down Expand Up @@ -840,6 +867,7 @@ func init() {
MustRegisterCmd("getblock", (*GetBlockCmd)(nil), flags)
MustRegisterCmd("getblockchaininfo", (*GetBlockChainInfoCmd)(nil), flags)
MustRegisterCmd("getblockcount", (*GetBlockCountCmd)(nil), flags)
MustRegisterCmd("getblockfilter", (*GetBlockFilterCmd)(nil), flags)
MustRegisterCmd("getblockhash", (*GetBlockHashCmd)(nil), flags)
MustRegisterCmd("getblockheader", (*GetBlockHeaderCmd)(nil), flags)
MustRegisterCmd("getblockstats", (*GetBlockStatsCmd)(nil), flags)
Expand Down
22 changes: 22 additions & 0 deletions btcjson/chainsvrcmds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,28 @@ func TestChainSvrCmds(t *testing.T) {
marshalled: `{"jsonrpc":"1.0","method":"getblockcount","params":[],"id":1}`,
unmarshalled: &btcjson.GetBlockCountCmd{},
},
{
name: "getblockfilter",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("getblockfilter", "0000afaf")
},
staticCmd: func() interface{} {
return btcjson.NewGetBlockFilterCmd("0000afaf", nil)
},
marshalled: `{"jsonrpc":"1.0","method":"getblockfilter","params":["0000afaf"],"id":1}`,
unmarshalled: &btcjson.GetBlockFilterCmd{"0000afaf", nil},
},
{
name: "getblockfilter optional filtertype",
newCmd: func() (interface{}, error) {
return btcjson.NewCmd("getblockfilter", "0000afaf", "basic")
},
staticCmd: func() interface{} {
return btcjson.NewGetBlockFilterCmd("0000afaf", btcjson.NewFilterTypeName(btcjson.FilterTypeBasic))
},
marshalled: `{"jsonrpc":"1.0","method":"getblockfilter","params":["0000afaf","basic"],"id":1}`,
unmarshalled: &btcjson.GetBlockFilterCmd{"0000afaf", btcjson.NewFilterTypeName(btcjson.FilterTypeBasic)},
},
{
name: "getblockhash",
newCmd: func() (interface{}, error) {
Expand Down
7 changes: 7 additions & 0 deletions btcjson/chainsvrresults.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,13 @@ type GetBlockChainInfoResult struct {
*UnifiedSoftForks
}

// GetBlockFilterResult models the data returned from the getblockfilter
// command.
type GetBlockFilterResult struct {
Filter string `json:"filter"` // the hex-encoded filter data
Header string `json:"header"` // the hex-encoded filter header
}

// GetBlockTemplateResultTx models the transactions field of the
// getblocktemplate command.
type GetBlockTemplateResultTx struct {
Expand Down
8 changes: 8 additions & 0 deletions btcjson/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,11 @@ func String(v string) *string {
*p = v
return p
}

// NewFilterTypeName is a helper routine that allocates a new FilterTypeName value to store v and
// returns a pointer to it. This is useful when assigning optional parameters.
func NewFilterTypeName(v FilterTypeName) *FilterTypeName {
p := new(FilterTypeName)
*p = v
return p
}
Comment on lines +81 to +85
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was about to comment that it might make sense to make the const FilterTypeBasic a var so it would be possible to do &FilterTypeBasic, but seems like you already anticipated this and added a nice solution:-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wasn't super happy about adding helper for this but it allows using const instead of var and is pretty consistent with how rpcclient API is used

38 changes: 38 additions & 0 deletions rpcclient/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,44 @@ func (c *Client) GetBlockChainInfo() (*btcjson.GetBlockChainInfoResult, error) {
return c.GetBlockChainInfoAsync().Receive()
}

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

// Receive waits for the response promised by the future and returns block filter
// result provided by the server.
func (r FutureGetBlockFilterResult) Receive() (*btcjson.GetBlockFilterResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}

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

return &blockFilter, nil
}

// GetBlockFilterAsync 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 GetBlockFilter for the blocking version and more details.
func (c *Client) GetBlockFilterAsync(blockHash chainhash.Hash, filterType *btcjson.FilterTypeName) FutureGetBlockFilterResult {
hash := blockHash.String()

cmd := btcjson.NewGetBlockFilterCmd(hash, filterType)
return c.sendCmd(cmd)
}

// GetBlockFilter retrieves a BIP0157 content filter for a particular block.
func (c *Client) GetBlockFilter(blockHash chainhash.Hash, filterType *btcjson.FilterTypeName) (*btcjson.GetBlockFilterResult, error) {
return c.GetBlockFilterAsync(blockHash, filterType).Receive()
}

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