mirror of
https://github.com/FlipsideCrypto/dcrd.git
synced 2026-02-06 10:56:47 +00:00
This commit introduces a new major version of the dcrjson module which
removes all dcrd RPC type support, instead focusing only on method and
type registration. The dcrd methods and types are moved to the
github.com/decred/dcrd/rpc/jsonrpc/types module.
In order to improve backwards compatibility with dcrjson/v2, the API
has been modified to register methods as interface{} instead of
string. This allows different method string types to be used to key
parameter types during registration and lookup, and will allow
dcrjson/v2 to forward registrations of RPC methods to v3 without
causing duplicate registrations errors for incompatible types.
With the introduction of the new types package, the RPC API has been
modified to replace concatenated hash blobs to JSON string arrays of
hash strings. The RPC API major version is bumped to reflect this
change.
A future update to dcrjson/v2 will add additional registrations,
forwarding the registrations to v3 and replacing command types with
type aliases where possible. Unfortunately, this can not be done
entirely in a single commit due to dcrjson/v2 and dcrjson/v3 sharing
the same directory in the source tree, and a branch will need to be
used for this update.
Module replacements are temporarily used to enable the changes for the
main module, including dcrctl. After the aforementioned update to
dcrjson/v2 and a forthcoming update to dcrwallet's RPC types package,
these replacements will be removed.
150 lines
4.8 KiB
Go
150 lines
4.8 KiB
Go
// Copyright (c) 2014 The btcsuite developers
|
|
// Copyright (c) 2015-2019 The Decred developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package dcrjson
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
// This example demonstrates how to create and marshal a command into a JSON-RPC
|
|
// request.
|
|
func ExampleMarshalCmd() {
|
|
// Create a new getblock command. Notice the nil parameter indicates
|
|
// to use the default parameter for that fields. This is a common
|
|
// pattern used in all of the New<Foo>Cmd functions in this package for
|
|
// optional fields. Also, notice the call to Bool which is a
|
|
// convenience function for creating a pointer out of a primitive for
|
|
// optional parameters.
|
|
//
|
|
// testGetBlockCmd was registered at init by the test.
|
|
blockHash := "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
|
gbCmd := &testGetBlockCmd{Hash: blockHash, Verbose: Bool(false), VerboseTx: nil}
|
|
|
|
// Marshal the command to the format suitable for sending to the RPC
|
|
// server. Typically the client would increment the id here which is
|
|
// request so the response can be identified.
|
|
id := 1
|
|
marshalledBytes, err := MarshalCmd("1.0", id, gbCmd)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
// Display the marshalled command. Ordinarily this would be sent across
|
|
// the wire to the RPC server, but for this example, just display it.
|
|
fmt.Printf("%s\n", marshalledBytes)
|
|
|
|
// Output:
|
|
// {"jsonrpc":"1.0","method":"getblock","params":["000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",false],"id":1}
|
|
}
|
|
|
|
// This example demonstrates how to unmarshal a JSON-RPC request and then
|
|
// parse the parameters into a concrete type.
|
|
func ExampleParseParams() {
|
|
// Ordinarily this would be read from the wire, but for this example,
|
|
// it is hard coded here for clarity.
|
|
data := []byte(`{"jsonrpc":"1.0","method":"getblock","params":["000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",false],"id":1}`)
|
|
|
|
// Unmarshal the raw bytes from the wire into a JSON-RPC request.
|
|
var request Request
|
|
if err := json.Unmarshal(data, &request); err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
// Typically there isn't any need to examine the request fields directly
|
|
// like this as the caller already knows what response to expect based
|
|
// on the command it sent. However, this is done here to demonstrate
|
|
// why the unmarshal process is two steps.
|
|
if request.ID == nil {
|
|
fmt.Println("Unexpected notification")
|
|
return
|
|
}
|
|
if request.Method != "getblock" {
|
|
fmt.Println("Unexpected method")
|
|
return
|
|
}
|
|
|
|
// Unmarshal the request into concrete params.
|
|
params, err := ParseParams(request.Method, request.Params)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
// Type assert the params to the appropriate type.
|
|
gbCmd, ok := params.(*testGetBlockCmd)
|
|
if !ok {
|
|
fmt.Printf("Incorrect params type: %T\n", params)
|
|
return
|
|
}
|
|
|
|
// Display the fields in the concrete command.
|
|
fmt.Println("Hash:", gbCmd.Hash)
|
|
fmt.Println("Verbose:", *gbCmd.Verbose)
|
|
fmt.Println("VerboseTx:", *gbCmd.VerboseTx)
|
|
|
|
// Output:
|
|
// Hash: 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
|
|
// Verbose: false
|
|
// VerboseTx: false
|
|
}
|
|
|
|
// This example demonstrates how to marshal a JSON-RPC response.
|
|
func ExampleMarshalResponse() {
|
|
// Marshal a new JSON-RPC response. For example, this is a response
|
|
// to a getblockheight request.
|
|
marshalledBytes, err := MarshalResponse("1.0", 1, 350001, nil)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
// Display the marshalled response. Ordinarily this would be sent
|
|
// across the wire to the RPC client, but for this example, just display
|
|
// it.
|
|
fmt.Printf("%s\n", marshalledBytes)
|
|
|
|
// Output:
|
|
// {"jsonrpc":"1.0","result":350001,"error":null,"id":1}
|
|
}
|
|
|
|
// This example demonstrates how to unmarshal a JSON-RPC response and then
|
|
// unmarshal the result field in the response to a concrete type.
|
|
func Example_unmarshalResponse() {
|
|
// Ordinarily this would be read from the wire, but for this example,
|
|
// it is hard coded here for clarity. This is an example response to a
|
|
// getblockheight request.
|
|
data := []byte(`{"result":350001,"error":null,"id":1}`)
|
|
|
|
// Unmarshal the raw bytes from the wire into a JSON-RPC response.
|
|
var response Response
|
|
if err := json.Unmarshal(data, &response); err != nil {
|
|
fmt.Println("Malformed JSON-RPC response:", err)
|
|
return
|
|
}
|
|
|
|
// Check the response for an error from the server. For example, the
|
|
// server might return an error if an invalid/unknown block hash is
|
|
// requested.
|
|
if response.Error != nil {
|
|
fmt.Println(response.Error)
|
|
return
|
|
}
|
|
|
|
// Unmarshal the result into the expected type for the response.
|
|
var blockHeight int32
|
|
if err := json.Unmarshal(response.Result, &blockHeight); err != nil {
|
|
fmt.Printf("Unexpected result type: %T\n", response.Result)
|
|
return
|
|
}
|
|
fmt.Println("Block height:", blockHeight)
|
|
|
|
// Output:
|
|
// Block height: 350001
|
|
}
|