Refactor FutureGetBlockVerboseResult into two types: FutureGetBlockVerboseResult, and FutureGetBlockVerboseTxResult.
Due to differences in how getblock returns data based on the provided verbosity parameter, it's necessary to have two separate return types based on verbosity. This necessitates a separate unmarshalling function (represented throughout rpcclient/chain.go as Result.Receive()) to ensure that data is correctly unmarshalled and returned to the user.
This commit is contained in:
parent
468154a052
commit
57cb8e4b11
5 changed files with 46 additions and 35 deletions
|
@ -142,50 +142,43 @@ func TestChainSvrCmds(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "getblock",
|
name: "getblock",
|
||||||
newCmd: func() (interface{}, error) {
|
newCmd: func() (interface{}, error) {
|
||||||
return btcjson.NewCmd("getblock", "123")
|
return btcjson.NewCmd("getblock", "123", btcjson.Int(0))
|
||||||
},
|
},
|
||||||
staticCmd: func() interface{} {
|
staticCmd: func() interface{} {
|
||||||
return btcjson.NewGetBlockCmd("123", nil, nil)
|
return btcjson.NewGetBlockCmd("123", btcjson.Int(0))
|
||||||
},
|
},
|
||||||
marshalled: `{"jsonrpc":"1.0","method":"getblock","params":["123"],"id":1}`,
|
marshalled: `{"jsonrpc":"1.0","method":"getblock","params":["123",0],"id":1}`,
|
||||||
unmarshalled: &btcjson.GetBlockCmd{
|
unmarshalled: &btcjson.GetBlockCmd{
|
||||||
Hash: "123",
|
Hash: "123",
|
||||||
Verbose: btcjson.Bool(true),
|
Verbosity: btcjson.Int(0),
|
||||||
VerboseTx: btcjson.Bool(false),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "getblock required optional1",
|
name: "getblock required optional1",
|
||||||
newCmd: func() (interface{}, error) {
|
newCmd: func() (interface{}, error) {
|
||||||
// Intentionally use a source param that is
|
return btcjson.NewCmd("getblock", "123", btcjson.Int(1))
|
||||||
// more pointers than the destination to
|
|
||||||
// exercise that path.
|
|
||||||
verbosePtr := btcjson.Bool(true)
|
|
||||||
return btcjson.NewCmd("getblock", "123", &verbosePtr)
|
|
||||||
},
|
},
|
||||||
staticCmd: func() interface{} {
|
staticCmd: func() interface{} {
|
||||||
return btcjson.NewGetBlockCmd("123", btcjson.Bool(true), nil)
|
return btcjson.NewGetBlockCmd("123", btcjson.Int(1))
|
||||||
},
|
},
|
||||||
marshalled: `{"jsonrpc":"1.0","method":"getblock","params":["123",true],"id":1}`,
|
marshalled: `{"jsonrpc":"1.0","method":"getblock","params":["123",1],"id":1}`,
|
||||||
unmarshalled: &btcjson.GetBlockCmd{
|
unmarshalled: &btcjson.GetBlockCmd{
|
||||||
Hash: "123",
|
Hash: "123",
|
||||||
Verbose: btcjson.Bool(true),
|
Verbosity: btcjson.Int(1),
|
||||||
VerboseTx: btcjson.Bool(false),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "getblock required optional2",
|
name: "getblock required optional2",
|
||||||
newCmd: func() (interface{}, error) {
|
newCmd: func() (interface{}, error) {
|
||||||
return btcjson.NewCmd("getblock", "123", true, true)
|
return btcjson.NewCmd("getblock", "123", btcjson.Int(2))
|
||||||
},
|
},
|
||||||
staticCmd: func() interface{} {
|
staticCmd: func() interface{} {
|
||||||
return btcjson.NewGetBlockCmd("123", btcjson.Bool(true), btcjson.Bool(true))
|
return btcjson.NewGetBlockCmd("123", btcjson.Int(2))
|
||||||
},
|
},
|
||||||
marshalled: `{"jsonrpc":"1.0","method":"getblock","params":["123",true,true],"id":1}`,
|
marshalled: `{"jsonrpc":"1.0","method":"getblock","params":["123",2],"id":1}`,
|
||||||
unmarshalled: &btcjson.GetBlockCmd{
|
unmarshalled: &btcjson.GetBlockCmd{
|
||||||
Hash: "123",
|
Hash: "123",
|
||||||
Verbose: btcjson.Bool(true),
|
Verbosity: btcjson.Int(2),
|
||||||
VerboseTx: btcjson.Bool(true),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -151,7 +151,7 @@ func TestMethodUsageText(t *testing.T) {
|
||||||
{
|
{
|
||||||
name: "getblock",
|
name: "getblock",
|
||||||
method: "getblock",
|
method: "getblock",
|
||||||
expected: `getblock "hash" (verbose=true verbosetx=false)`,
|
expected: `getblock "hash" (verbosity=1)`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ func ExampleMarshalCmd() {
|
||||||
// convenience function for creating a pointer out of a primitive for
|
// convenience function for creating a pointer out of a primitive for
|
||||||
// optional parameters.
|
// optional parameters.
|
||||||
blockHash := "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
blockHash := "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
||||||
gbCmd := btcjson.NewGetBlockCmd(blockHash, btcjson.Bool(false), nil)
|
gbCmd := btcjson.NewGetBlockCmd(blockHash, btcjson.Int(1))
|
||||||
|
|
||||||
// Marshal the command to the format suitable for sending to the RPC
|
// Marshal the command to the format suitable for sending to the RPC
|
||||||
// server. Typically the client would increment the id here which is
|
// server. Typically the client would increment the id here which is
|
||||||
|
@ -38,7 +38,7 @@ func ExampleMarshalCmd() {
|
||||||
fmt.Printf("%s\n", marshalledBytes)
|
fmt.Printf("%s\n", marshalledBytes)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// {"jsonrpc":"1.0","method":"getblock","params":["000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",false],"id":1}
|
// {"jsonrpc":"1.0","method":"getblock","params":["000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",1],"id":1}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This example demonstrates how to unmarshal a JSON-RPC request and then
|
// This example demonstrates how to unmarshal a JSON-RPC request and then
|
||||||
|
@ -46,7 +46,7 @@ func ExampleMarshalCmd() {
|
||||||
func ExampleUnmarshalCmd() {
|
func ExampleUnmarshalCmd() {
|
||||||
// Ordinarily this would be read from the wire, but for this example,
|
// Ordinarily this would be read from the wire, but for this example,
|
||||||
// it is hard coded here for clarity.
|
// it is hard coded here for clarity.
|
||||||
data := []byte(`{"jsonrpc":"1.0","method":"getblock","params":["000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",false],"id":1}`)
|
data := []byte(`{"jsonrpc":"1.0","method":"getblock","params":["000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",1],"id":1}`)
|
||||||
|
|
||||||
// Unmarshal the raw bytes from the wire into a JSON-RPC request.
|
// Unmarshal the raw bytes from the wire into a JSON-RPC request.
|
||||||
var request btcjson.Request
|
var request btcjson.Request
|
||||||
|
@ -84,13 +84,11 @@ func ExampleUnmarshalCmd() {
|
||||||
|
|
||||||
// Display the fields in the concrete command.
|
// Display the fields in the concrete command.
|
||||||
fmt.Println("Hash:", gbCmd.Hash)
|
fmt.Println("Hash:", gbCmd.Hash)
|
||||||
fmt.Println("Verbose:", *gbCmd.Verbose)
|
fmt.Println("Verbosity:", *gbCmd.Verbosity)
|
||||||
fmt.Println("VerboseTx:", *gbCmd.VerboseTx)
|
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
// Hash: 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
|
// Hash: 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
|
||||||
// Verbose: false
|
// Verbosity: 0
|
||||||
// VerboseTx: false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This example demonstrates how to marshal a JSON-RPC response.
|
// This example demonstrates how to marshal a JSON-RPC response.
|
||||||
|
|
|
@ -97,7 +97,7 @@ func (c *Client) GetBlockAsync(blockHash *chainhash.Hash) FutureGetBlockResult {
|
||||||
hash = blockHash.String()
|
hash = blockHash.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(false), nil)
|
cmd := btcjson.NewGetBlockCmd(hash, nil)
|
||||||
return c.sendCmd(cmd)
|
return c.sendCmd(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,8 +140,9 @@ func (c *Client) GetBlockVerboseAsync(blockHash *chainhash.Hash) FutureGetBlockV
|
||||||
if blockHash != nil {
|
if blockHash != nil {
|
||||||
hash = blockHash.String()
|
hash = blockHash.String()
|
||||||
}
|
}
|
||||||
|
// From the bitcoin-cli getblock documentation:
|
||||||
cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(true), nil)
|
// "If verbosity is 1, returns an Object with information about block ."
|
||||||
|
cmd := btcjson.NewGetBlockCmd(hash, btcjson.Int(1))
|
||||||
return c.sendCmd(cmd)
|
return c.sendCmd(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,18 +155,37 @@ func (c *Client) GetBlockVerbose(blockHash *chainhash.Hash) (*btcjson.GetBlockVe
|
||||||
return c.GetBlockVerboseAsync(blockHash).Receive()
|
return c.GetBlockVerboseAsync(blockHash).Receive()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FutureGetBlockVerboseTxResult chan *response
|
||||||
|
|
||||||
|
func (r FutureGetBlockVerboseTxResult) Receive() (*btcjson.GetBlockVerboseTxResult, error) {
|
||||||
|
res, err := receiveFuture(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var blockResult btcjson.GetBlockVerboseTxResult
|
||||||
|
err = json.Unmarshal(res, &blockResult)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &blockResult, nil
|
||||||
|
}
|
||||||
|
|
||||||
// GetBlockVerboseTxAsync returns an instance of a type that can be used to get
|
// GetBlockVerboseTxAsync 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 result of the RPC at some future time by invoking the Receive function on
|
||||||
// the returned instance.
|
// the returned instance.
|
||||||
//
|
//
|
||||||
// See GetBlockVerboseTx or the blocking version and more details.
|
// See GetBlockVerboseTx or the blocking version and more details.
|
||||||
func (c *Client) GetBlockVerboseTxAsync(blockHash *chainhash.Hash) FutureGetBlockVerboseResult {
|
func (c *Client) GetBlockVerboseTxAsync(blockHash *chainhash.Hash) FutureGetBlockVerboseTxResult {
|
||||||
hash := ""
|
hash := ""
|
||||||
if blockHash != nil {
|
if blockHash != nil {
|
||||||
hash = blockHash.String()
|
hash = blockHash.String()
|
||||||
}
|
}
|
||||||
|
// From the bitcoin-cli getblock documentation:
|
||||||
|
// "If verbosity is 2, returns an Object with information about block and information about each transaction."
|
||||||
|
cmd := btcjson.NewGetBlockCmd(hash, btcjson.Int(2))
|
||||||
|
|
||||||
cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(true), btcjson.Bool(true))
|
|
||||||
return c.sendCmd(cmd)
|
return c.sendCmd(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +194,7 @@ func (c *Client) GetBlockVerboseTxAsync(blockHash *chainhash.Hash) FutureGetBloc
|
||||||
//
|
//
|
||||||
// See GetBlockVerbose if only transaction hashes are preferred.
|
// See GetBlockVerbose if only transaction hashes are preferred.
|
||||||
// See GetBlock to retrieve a raw block instead.
|
// See GetBlock to retrieve a raw block instead.
|
||||||
func (c *Client) GetBlockVerboseTx(blockHash *chainhash.Hash) (*btcjson.GetBlockVerboseResult, error) {
|
func (c *Client) GetBlockVerboseTx(blockHash *chainhash.Hash) (*btcjson.GetBlockVerboseTxResult, error) {
|
||||||
return c.GetBlockVerboseTxAsync(blockHash).Receive()
|
return c.GetBlockVerboseTxAsync(blockHash).Receive()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1084,7 +1084,7 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
|
||||||
|
|
||||||
// When the verbose flag isn't set, simply return the serialized block
|
// When the verbose flag isn't set, simply return the serialized block
|
||||||
// as a hex-encoded string.
|
// as a hex-encoded string.
|
||||||
if c.Verbose != nil && !*c.Verbose {
|
if c.Verbosity != nil && *c.Verbosity == 0 {
|
||||||
return hex.EncodeToString(blkBytes), nil
|
return hex.EncodeToString(blkBytes), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1137,7 +1137,7 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
|
||||||
NextHash: nextHashString,
|
NextHash: nextHashString,
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.VerboseTx == nil || !*c.VerboseTx {
|
if *c.Verbosity == 1 {
|
||||||
transactions := blk.Transactions()
|
transactions := blk.Transactions()
|
||||||
txNames := make([]string, len(transactions))
|
txNames := make([]string, len(transactions))
|
||||||
for i, tx := range transactions {
|
for i, tx := range transactions {
|
||||||
|
|
Loading…
Reference in a new issue