mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
[DEV-317] Update JSON-RPC API call GetBlock to allow filtering by SubNetworkID (#180)
* [DEV-317] Update JSON-RPC API call GetBlock to allow filtering by SubNetworkID * [DEV-317] Changed comments, messages and refactored code
This commit is contained in:
parent
0bc7a11551
commit
3eeff11231
@ -151,7 +151,7 @@ func TestMethodUsageText(t *testing.T) {
|
||||
{
|
||||
name: "getBlock",
|
||||
method: "getBlock",
|
||||
expected: `getBlock "hash" (verbose=true verbosetx=false)`,
|
||||
expected: `getBlock "hash" (verbose=true verbosetx=false "subnetwork")`,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -135,9 +135,10 @@ func NewGetBestBlockHashCmd() *GetBestBlockHashCmd {
|
||||
|
||||
// GetBlockCmd defines the getBlock JSON-RPC command.
|
||||
type GetBlockCmd struct {
|
||||
Hash string
|
||||
Verbose *bool `jsonrpcdefault:"true"`
|
||||
VerboseTx *bool `jsonrpcdefault:"false"`
|
||||
Hash string
|
||||
Verbose *bool `jsonrpcdefault:"true"`
|
||||
VerboseTx *bool `jsonrpcdefault:"false"`
|
||||
Subnetwork *string
|
||||
}
|
||||
|
||||
// NewGetBlockCmd returns a new instance which can be used to issue a getBlock
|
||||
@ -145,11 +146,12 @@ type GetBlockCmd struct {
|
||||
//
|
||||
// The parameters which are pointers indicate they are optional. Passing nil
|
||||
// for optional parameters will use the default value.
|
||||
func NewGetBlockCmd(hash string, verbose, verboseTx *bool) *GetBlockCmd {
|
||||
func NewGetBlockCmd(hash string, verbose, verboseTx *bool, subnetworkID *string) *GetBlockCmd {
|
||||
return &GetBlockCmd{
|
||||
Hash: hash,
|
||||
Verbose: verbose,
|
||||
VerboseTx: verboseTx,
|
||||
Hash: hash,
|
||||
Verbose: verbose,
|
||||
VerboseTx: verboseTx,
|
||||
Subnetwork: subnetworkID,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ func TestDAGSvrCmds(t *testing.T) {
|
||||
return btcjson.NewCmd("getBlock", "123")
|
||||
},
|
||||
staticCmd: func() interface{} {
|
||||
return btcjson.NewGetBlockCmd("123", nil, nil)
|
||||
return btcjson.NewGetBlockCmd("123", nil, nil, nil)
|
||||
},
|
||||
marshalled: `{"jsonrpc":"1.0","method":"getBlock","params":["123"],"id":1}`,
|
||||
unmarshalled: &btcjson.GetBlockCmd{
|
||||
@ -150,7 +150,7 @@ func TestDAGSvrCmds(t *testing.T) {
|
||||
return btcjson.NewCmd("getBlock", "123", &verbosePtr)
|
||||
},
|
||||
staticCmd: func() interface{} {
|
||||
return btcjson.NewGetBlockCmd("123", btcjson.Bool(true), nil)
|
||||
return btcjson.NewGetBlockCmd("123", btcjson.Bool(true), nil, nil)
|
||||
},
|
||||
marshalled: `{"jsonrpc":"1.0","method":"getBlock","params":["123",true],"id":1}`,
|
||||
unmarshalled: &btcjson.GetBlockCmd{
|
||||
@ -165,7 +165,7 @@ func TestDAGSvrCmds(t *testing.T) {
|
||||
return btcjson.NewCmd("getBlock", "123", true, true)
|
||||
},
|
||||
staticCmd: func() interface{} {
|
||||
return btcjson.NewGetBlockCmd("123", btcjson.Bool(true), btcjson.Bool(true))
|
||||
return btcjson.NewGetBlockCmd("123", btcjson.Bool(true), btcjson.Bool(true), nil)
|
||||
},
|
||||
marshalled: `{"jsonrpc":"1.0","method":"getBlock","params":["123",true,true],"id":1}`,
|
||||
unmarshalled: &btcjson.GetBlockCmd{
|
||||
@ -174,6 +174,22 @@ func TestDAGSvrCmds(t *testing.T) {
|
||||
VerboseTx: btcjson.Bool(true),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "getBlock required optional3",
|
||||
newCmd: func() (interface{}, error) {
|
||||
return btcjson.NewCmd("getBlock", "123", true, true, "456")
|
||||
},
|
||||
staticCmd: func() interface{} {
|
||||
return btcjson.NewGetBlockCmd("123", btcjson.Bool(true), btcjson.Bool(true), btcjson.String("456"))
|
||||
},
|
||||
marshalled: `{"jsonrpc":"1.0","method":"getBlock","params":["123",true,true,"456"],"id":1}`,
|
||||
unmarshalled: &btcjson.GetBlockCmd{
|
||||
Hash: "123",
|
||||
Verbose: btcjson.Bool(true),
|
||||
VerboseTx: btcjson.Bool(true),
|
||||
Subnetwork: btcjson.String("456"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "getBlockDagInfo",
|
||||
newCmd: func() (interface{}, error) {
|
||||
|
@ -21,7 +21,7 @@ func ExampleMarshalCmd() {
|
||||
// convenience function for creating a pointer out of a primitive for
|
||||
// optional parameters.
|
||||
blockHash := "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
||||
gbCmd := btcjson.NewGetBlockCmd(blockHash, btcjson.Bool(false), nil)
|
||||
gbCmd := btcjson.NewGetBlockCmd(blockHash, btcjson.Bool(false), nil, nil)
|
||||
|
||||
// Marshal the command to the format suitable for sending to the RPC
|
||||
// server. Typically the client would increment the id here which is
|
||||
@ -86,6 +86,9 @@ func ExampleUnmarshalCmd() {
|
||||
fmt.Println("Hash:", gbCmd.Hash)
|
||||
fmt.Println("Verbose:", *gbCmd.Verbose)
|
||||
fmt.Println("VerboseTx:", *gbCmd.VerboseTx)
|
||||
if gbCmd.Subnetwork != nil {
|
||||
fmt.Println("Subnetwork:", *gbCmd.Subnetwork)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// Hash: 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
|
||||
|
@ -439,7 +439,7 @@ func (h *Harness) GenerateAndSubmitBlockWithCustomCoinbaseOutputs(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mBlock, err := h.Node.GetBlock(parentBlockHash)
|
||||
mBlock, err := h.Node.GetBlock(parentBlockHash, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -91,13 +91,13 @@ func (r FutureGetBlockResult) Receive() (*wire.MsgBlock, error) {
|
||||
// returned instance.
|
||||
//
|
||||
// See GetBlock for the blocking version and more details.
|
||||
func (c *Client) GetBlockAsync(blockHash *daghash.Hash) FutureGetBlockResult {
|
||||
func (c *Client) GetBlockAsync(blockHash *daghash.Hash, subnetworkID *string) FutureGetBlockResult {
|
||||
hash := ""
|
||||
if blockHash != nil {
|
||||
hash = blockHash.String()
|
||||
}
|
||||
|
||||
cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(false), nil)
|
||||
cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(false), btcjson.Bool(false), subnetworkID)
|
||||
return c.sendCmd(cmd)
|
||||
}
|
||||
|
||||
@ -105,8 +105,8 @@ func (c *Client) GetBlockAsync(blockHash *daghash.Hash) FutureGetBlockResult {
|
||||
//
|
||||
// See GetBlockVerbose to retrieve a data structure with information about the
|
||||
// block instead.
|
||||
func (c *Client) GetBlock(blockHash *daghash.Hash) (*wire.MsgBlock, error) {
|
||||
return c.GetBlockAsync(blockHash).Receive()
|
||||
func (c *Client) GetBlock(blockHash *daghash.Hash, subnetworkID *string) (*wire.MsgBlock, error) {
|
||||
return c.GetBlockAsync(blockHash, subnetworkID).Receive()
|
||||
}
|
||||
|
||||
// FutureGetBlockVerboseResult is a future promise to deliver the result of a
|
||||
@ -135,13 +135,13 @@ func (r FutureGetBlockVerboseResult) Receive() (*btcjson.GetBlockVerboseResult,
|
||||
// the returned instance.
|
||||
//
|
||||
// See GetBlockVerbose for the blocking version and more details.
|
||||
func (c *Client) GetBlockVerboseAsync(blockHash *daghash.Hash) FutureGetBlockVerboseResult {
|
||||
func (c *Client) GetBlockVerboseAsync(blockHash *daghash.Hash, subnetworkID *string) FutureGetBlockVerboseResult {
|
||||
hash := ""
|
||||
if blockHash != nil {
|
||||
hash = blockHash.String()
|
||||
}
|
||||
|
||||
cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(true), nil)
|
||||
cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(true), btcjson.Bool(false), subnetworkID)
|
||||
return c.sendCmd(cmd)
|
||||
}
|
||||
|
||||
@ -150,8 +150,8 @@ func (c *Client) GetBlockVerboseAsync(blockHash *daghash.Hash) FutureGetBlockVer
|
||||
//
|
||||
// See GetBlockVerboseTx to retrieve transaction data structures as well.
|
||||
// See GetBlock to retrieve a raw block instead.
|
||||
func (c *Client) GetBlockVerbose(blockHash *daghash.Hash) (*btcjson.GetBlockVerboseResult, error) {
|
||||
return c.GetBlockVerboseAsync(blockHash).Receive()
|
||||
func (c *Client) GetBlockVerbose(blockHash *daghash.Hash, subnetworkID *string) (*btcjson.GetBlockVerboseResult, error) {
|
||||
return c.GetBlockVerboseAsync(blockHash, subnetworkID).Receive()
|
||||
}
|
||||
|
||||
// GetBlockVerboseTxAsync returns an instance of a type that can be used to get
|
||||
@ -159,13 +159,13 @@ func (c *Client) GetBlockVerbose(blockHash *daghash.Hash) (*btcjson.GetBlockVerb
|
||||
// the returned instance.
|
||||
//
|
||||
// See GetBlockVerboseTx or the blocking version and more details.
|
||||
func (c *Client) GetBlockVerboseTxAsync(blockHash *daghash.Hash) FutureGetBlockVerboseResult {
|
||||
func (c *Client) GetBlockVerboseTxAsync(blockHash *daghash.Hash, subnetworkID *string) FutureGetBlockVerboseResult {
|
||||
hash := ""
|
||||
if blockHash != nil {
|
||||
hash = blockHash.String()
|
||||
}
|
||||
|
||||
cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(true), btcjson.Bool(true))
|
||||
cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(true), btcjson.Bool(true), subnetworkID)
|
||||
return c.sendCmd(cmd)
|
||||
}
|
||||
|
||||
@ -174,8 +174,8 @@ func (c *Client) GetBlockVerboseTxAsync(blockHash *daghash.Hash) FutureGetBlockV
|
||||
//
|
||||
// See GetBlockVerbose if only transaction hashes are preferred.
|
||||
// See GetBlock to retrieve a raw block instead.
|
||||
func (c *Client) GetBlockVerboseTx(blockHash *daghash.Hash) (*btcjson.GetBlockVerboseResult, error) {
|
||||
return c.GetBlockVerboseTxAsync(blockHash).Receive()
|
||||
func (c *Client) GetBlockVerboseTx(blockHash *daghash.Hash, subnetworkID *string) (*btcjson.GetBlockVerboseResult, error) {
|
||||
return c.GetBlockVerboseTxAsync(blockHash, subnetworkID).Receive()
|
||||
}
|
||||
|
||||
// FutureGetBlockCountResult is a future promise to deliver the result of a
|
||||
|
@ -6,6 +6,7 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"crypto/subtle"
|
||||
@ -47,6 +48,7 @@ import (
|
||||
"github.com/daglabs/btcd/util"
|
||||
"github.com/daglabs/btcd/util/fs"
|
||||
"github.com/daglabs/btcd/util/network"
|
||||
"github.com/daglabs/btcd/util/subnetworkid"
|
||||
"github.com/daglabs/btcd/version"
|
||||
"github.com/daglabs/btcd/wire"
|
||||
)
|
||||
@ -1107,6 +1109,42 @@ func handleGetBlock(s *Server, cmd interface{}, closeChan <-chan struct{}) (inte
|
||||
}
|
||||
}
|
||||
|
||||
// Handle partial blocks
|
||||
if c.Subnetwork != nil {
|
||||
requestSubnetworkID, err := subnetworkid.NewFromStr(*c.Subnetwork)
|
||||
if err != nil {
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCInvalidRequest.Code,
|
||||
Message: "invalid subnetwork string",
|
||||
}
|
||||
}
|
||||
nodeSubnetworkID := config.MainConfig().SubnetworkID
|
||||
|
||||
if !requestSubnetworkID.IsEqual(&wire.SubnetworkIDSupportsAll) {
|
||||
if !nodeSubnetworkID.IsEqual(&wire.SubnetworkIDSupportsAll) {
|
||||
if !nodeSubnetworkID.IsEqual(requestSubnetworkID) {
|
||||
return nil, &btcjson.RPCError{
|
||||
Code: btcjson.ErrRPCInvalidRequest.Code,
|
||||
Message: "subnetwork does not match this partial node",
|
||||
}
|
||||
}
|
||||
// nothing to do - partial node stores partial blocks
|
||||
} else {
|
||||
// Deserialize the block.
|
||||
var msgBlock wire.MsgBlock
|
||||
err = msgBlock.Deserialize(bytes.NewReader(blkBytes))
|
||||
if err != nil {
|
||||
context := "Failed to deserialize block"
|
||||
return nil, internalRPCError(err.Error(), context)
|
||||
}
|
||||
msgBlock.ConvertToPartial(requestSubnetworkID)
|
||||
var b bytes.Buffer
|
||||
msgBlock.Serialize(bufio.NewWriter(&b))
|
||||
blkBytes = b.Bytes()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When the verbose flag isn't set, simply return the serialized block
|
||||
// as a hex-encoded string.
|
||||
if c.Verbose != nil && !*c.Verbose {
|
||||
|
@ -169,6 +169,7 @@ var helpDescsEnUS = map[string]string{
|
||||
"getBlock-hash": "The hash of the block",
|
||||
"getBlock-verbose": "Specifies the block is returned as a JSON object instead of hex-encoded string",
|
||||
"getBlock-verboseTx": "Specifies that each transaction is returned as a JSON object and only applies if the verbose flag is true (btcd extension)",
|
||||
"getBlock-subnetwork": "If passed, the returned block will be a partial block of the specified subnetwork",
|
||||
"getBlock--condition0": "verbose=false",
|
||||
"getBlock--condition1": "verbose=true",
|
||||
"getBlock-acceptedTx": "Specifies if the transaction got accepted",
|
||||
|
Loading…
x
Reference in New Issue
Block a user