dcrjson

package module
v3.0.0-...-3464dac Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 8, 2020 License: ISC Imports: 11 Imported by: 2

README

dcrjson

Build Status ISC License Doc

Package dcrjson implements infrastructure for marshalling to and from the hdfchain JSON-RPC API via concrete types. A comprehensive suite of tests is provided to ensure proper functionality.

Although this package was primarily written for the hdfchain, it has intentionally been designed so it can be used as a standalone package for any projects needing to marshal to and from hdfchain JSON-RPC requests and responses.

Note that although it's possible to use this package directly to implement an RPC client, it is not recommended since it is only intended as an infrastructure package. Instead, RPC clients should use the rpcclient package which provides a full blown RPC client with many features such as automatic connection management, websocket support, automatic notification re-registration on reconnect, and conversion from the raw underlying RPC types (strings, floats, ints, etc) to higher-level types with many nice and useful properties.

Installation and Updating

$ go get -u github.com/hdfchain/hdfd/dcrjson

Examples

  • Marshal Command Demonstrates how to create and marshal a command into a JSON-RPC request.

  • Parse Command Demonstrates how to unmarshal a JSON-RPC request and then parse the params of the concrete request into a concrete command.

  • Marshal Response Demonstrates how to marshal a JSON-RPC response.

  • Unmarshal Response Demonstrates how to unmarshal a JSON-RPC response and then unmarshal the result field in the response to a concrete type.

License

Package dcrjson is licensed under the copyfree ISC License.

Documentation

Overview

Package dcrjson provides infrastructure for working with Hdfchain JSON-RPC APIs.

When communicating via the JSON-RPC protocol, all requests and responses must be marshalled to and from the wire in the appropriate format. This package provides infrastructure and primitives to ease this process.

JSON-RPC Protocol Overview

This information is not necessary in order to use this package, but it does provide some intuition into what the marshalling and unmarshalling that is discussed below is doing under the hood.

As defined by the JSON-RPC spec, there are effectively two forms of messages on the wire:

  • Request Objects {"jsonrpc":"1.0","id":"SOMEID","method":"SOMEMETHOD","params":[SOMEPARAMS]} NOTE: Notifications are the same format except the id field is null.

  • Response Objects {"result":SOMETHING,"error":null,"id":"SOMEID"} {"result":null,"error":{"code":SOMEINT,"message":SOMESTRING},"id":"SOMEID"}

For requests, the params field can vary in what it contains depending on the method (a.k.a. command) being sent. Each parameter can be as simple as an int or a complex structure containing many nested fields. The id field is used to identify a request and will be included in the associated response.

When working with streamed RPC transports, such as websockets, spontaneous notifications are also possible. As indicated, they are the same as a request object, except they have the id field set to null. Therefore, servers will ignore requests with the id field set to null, while clients can choose to consume or ignore them.

Unfortunately, the original Bitcoin JSON-RPC API (and hence anything compatible with it) doesn't always follow the spec and will sometimes return an error string in the result field with a null error for certain commands. However, for the most part, the error field will be set as described on failure.

Marshalling and Unmarshalling

To simplify the marshalling of the requests and responses, the MarshalCmd and MarshalResponse functions are provided. They return the raw bytes ready to be sent across the wire.

Unmarshalling a received Request object is a two step process:

  1. Unmarshal the raw bytes into a Request struct instance via json.Unmarshal
  2. Use ParseParams on the Method and Params fields of the unmarshalled Request to create a concrete command or notification instance with all struct fields set accordingly. The concrete types must have been registered for the method by an external package

This approach is used since it provides the caller with access to the additional fields in the request that are not part of the command such as the ID.

Unmarshalling a received Response object is also a two step process:

  1. Unmarshal the raw bytes into a Response struct instance via json.Unmarshal
  2. Depending on the ID, unmarshal the Result field of the unmarshalled Response to create a concrete type instance

As above, this approach is used since it provides the caller with access to the fields in the response such as the ID and Error.

Command Creation

This package provides the NewCmd function which takes a method (command) name and variable arguments. The function includes full checking to ensure the parameters are accurate according to provided method, however these checks are, obviously, run-time which means any mistakes won't be found until the code is actually executed. However, it is quite useful for user-supplied commands that are intentionally dynamic.

External packages can and should implement types implementing Command for use with MarshalCmd/ParseParams.

Custom Command Registration

The command handling of this package is built around the concept of registered commands. This is true for the wide variety of commands already provided by the package, but it also means caller can easily provide custom commands with all of the same functionality as the built-in commands. Use the RegisterCmd function for this purpose.

A list of all registered methods can be obtained with the RegisteredCmdMethods function.

Command Inspection

All registered commands are registered with flags that identify information such as whether the command applies to a chain server, wallet server, or is a notification along with the method name to use. These flags can be obtained with the MethodUsageFlags flags, and the method can be obtained with the CmdMethod function.

Help Generation

To facilitate providing consistent help to users of the RPC server, this package exposes the GenerateHelp and function which uses reflection on registered commands or notifications to generate the final help text.

In addition, the MethodUsageText function is provided to generate consistent one-line usage for registered commands and notifications using reflection.

Errors

There are 2 distinct type of errors supported by this package:

  • General errors related to marshalling or unmarshalling or improper use of the package (type Error)
  • RPC errors which are intended to be returned across the wire as a part of the JSON-RPC response (type RPCError)

The first category of errors (type Error) typically indicates a programmer error and can be avoided by properly using the API. Errors of this type will be returned from the various functions available in this package. They identify issues such as unsupported field types, attempts to register malformed commands, and attempting to create a new command with an improper number of parameters. The specific reason for the error can be detected by type asserting it to a *dcrjson.Error and accessing the ErrorCode field.

The second category of errors (type RPCError), on the other hand, are useful for returning errors to RPC clients. Consequently, they are used in the previously described Response type.

Example (UnmarshalResponse)

This example demonstrates how to unmarshal a JSON-RPC response and then unmarshal the result field in the response to a concrete type.

// 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

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidRequest = Error{
		Code:    -32600,
		Message: "Invalid request",
	}
	ErrMethodNotFound = Error{
		Code:    -32601,
		Message: "Method not found",
	}
	ErrInvalidParams = Error{
		Code:    -32602,
		Message: "Invalid parameters",
	}
	ErrInternal = Error{
		Code:    -32603,
		Message: "Internal error",
	}
	ErrParse = Error{
		Code:    -32700,
		Message: "Parse error",
	}
)

Standard JSON-RPC 2.0 errors

View Source
var (
	ErrMisc = Error{
		Code:    -1,
		Message: "Miscellaneous error",
	}
	ErrForbiddenBySafeMode = Error{
		Code:    -2,
		Message: "Server is in safe mode, and command is not allowed in safe mode",
	}
	ErrType = Error{
		Code:    -3,
		Message: "Unexpected type was passed as parameter",
	}
	ErrInvalidAddressOrKey = Error{
		Code:    -5,
		Message: "Invalid address or key",
	}
	ErrOutOfMemory = Error{
		Code:    -7,
		Message: "Ran out of memory during operation",
	}
	ErrInvalidParameter = Error{
		Code:    -8,
		Message: "Invalid, missing or duplicate parameter",
	}
	ErrDatabase = Error{
		Code:    -20,
		Message: "Database error",
	}
	ErrDeserialization = Error{
		Code:    -22,
		Message: "Error parsing or validating structure in raw format",
	}
)

General application defined JSON errors

View Source
var (
	ErrClientNotConnected = Error{
		Code:    -9,
		Message: "hdfd is not connected",
	}
	ErrClientInInitialDownload = Error{
		Code:    -10,
		Message: "hdfd is downloading blocks...",
	}
)

Peer-to-peer client errors

View Source
var (
	ErrWallet = Error{
		Code:    -4,
		Message: "Unspecified problem with wallet",
	}
	ErrWalletInsufficientFunds = Error{
		Code:    -6,
		Message: "Not enough funds in wallet or account",
	}
	ErrWalletInvalidAccountName = Error{
		Code:    -11,
		Message: "Invalid account name",
	}
	ErrWalletKeypoolRanOut = Error{
		Code:    -12,
		Message: "Keypool ran out, call keypoolrefill first",
	}
	ErrWalletUnlockNeeded = Error{
		Code:    -13,
		Message: "Enter the wallet passphrase with walletpassphrase first",
	}
	ErrWalletPassphraseIncorrect = Error{
		Code:    -14,
		Message: "The wallet passphrase entered was incorrect",
	}
	ErrWalletWrongEncState = Error{
		Code:    -15,
		Message: "Command given in wrong wallet encryption state",
	}
	ErrWalletEncryptionFailed = Error{
		Code:    -16,
		Message: "Failed to encrypt the wallet",
	}
	ErrWalletAlreadyUnlocked = Error{
		Code:    -17,
		Message: "Wallet is already unlocked",
	}
)

Wallet JSON errors

View Source
var (
	ErrBlockNotFound = Error{
		Code:    -5,
		Message: "Block not found",
	}
	ErrBlockCount = Error{
		Code:    -5,
		Message: "Error getting block count",
	}
	ErrBestBlockHash = Error{
		Code:    -5,
		Message: "Error getting best block hash",
	}
	ErrDifficulty = Error{
		Code:    -5,
		Message: "Error getting difficulty",
	}
	ErrOutOfRange = Error{
		Code:    -1,
		Message: "Block number out of range",
	}
	ErrNoTxInfo = Error{
		Code:    -5,
		Message: "No information available about transaction",
	}
	ErrNoNewestBlockInfo = Error{
		Code:    -5,
		Message: "No information about newest block",
	}
	ErrInvalidTxVout = Error{
		Code:    -5,
		Message: "Output index number (vout) does not exist for transaction.",
	}
	ErrRawTxString = Error{
		Code:    -32602,
		Message: "Raw tx is not a string",
	}
	ErrDecodeHexString = Error{
		Code:    -22,
		Message: "Unable to decode hex string",
	}
)

Specific Errors related to commands. These are the ones a user of the rpc server are most likely to see. Generally, the codes should match one of the more general errors above.

View Source
var (
	ErrNoWallet = Error{
		Code:    -1,
		Message: "This implementation does not implement wallet commands",
	}
	ErrUnimplemented = Error{
		Code:    -1,
		Message: "Command unimplemented",
	}
)

Errors that are specific to hdfd.

View Source
var (
	ErrRPCInvalidRequest = &RPCError{
		Code:    -32600,
		Message: "Invalid request",
	}
	ErrRPCMethodNotFound = &RPCError{
		Code:    -32601,
		Message: "Method not found",
	}
	ErrRPCInvalidParams = &RPCError{
		Code:    -32602,
		Message: "Invalid parameters",
	}
	ErrRPCInternal = &RPCError{
		Code:    -32603,
		Message: "Internal error",
	}
	ErrRPCParse = &RPCError{
		Code:    -32700,
		Message: "Parse error",
	}
)

Standard JSON-RPC 2.0 errors.

Functions

func Bool

func Bool(v bool) *bool

Bool is a helper routine that allocates a new bool value to store v and returns a pointer to it. This is useful when assigning optional parameters.

func CmdMethod

func CmdMethod(cmd interface{}) (string, error)

CmdMethod returns the method for the passed command. The provided command type must be a registered type. All commands provided by this package are registered by default.

func DecodeConcatenatedHashes

func DecodeConcatenatedHashes(hashes string) ([]chainhash.Hash, error)

DecodeConcatenatedHashes return a slice of contiguous chainhash.Hash objects created by decoding a single string of concatenated hex-encoded hashes.

These hashes must NOT be the byte reversed string encoding that is typically used for block and transaction hashes, or each resulting hash will also be reversed.

The length of the string must be evenly divisible by twice the hash size in order for the parameter to be valid. This function assumes the input is from a JSON-RPC request and any errors will be of type *RPCError with an ErrRPCInvalidParameter or ErrRPCDecodedHexString error code.

func EncodeConcatenatedHashes

func EncodeConcatenatedHashes(hashSlice []chainhash.Hash) string

EncodeConcatenatedHashes serializes a slice of chainhash.Hash values into a string of hex-encoded bytes.

func Float64

func Float64(v float64) *float64

Float64 is a helper routine that allocates a new float64 value to store v and returns a pointer to it. This is useful when assigning optional parameters.

func GenerateHelp

func GenerateHelp(method interface{}, descs map[string]string, resultTypes ...interface{}) (string, error)

GenerateHelp generates and returns help output for the provided method and result types given a map to provide the appropriate keys for the method synopsis, field descriptions, conditions, and result descriptions. The method must be associated with a registered type. All commands provided by this package are registered by default.

The resultTypes must be pointer-to-types which represent the specific types of values the command returns. For example, if the command only returns a boolean value, there should only be a single entry of (*bool)(nil). Note that each type must be a single pointer to the type. Therefore, it is recommended to simply pass a nil pointer cast to the appropriate type as previously shown.

The provided descriptions map must contain all of the keys or an error will be returned which includes the missing key, or the final missing key when there is more than one key missing. The generated help in the case of such an error will use the key in place of the description.

The following outlines the required keys:

"<method>--synopsis"             Synopsis for the command
"<method>-<lowerfieldname>"      Description for each command argument
"<typename>-<lowerfieldname>"    Description for each object field
"<method>--condition<#>"         Description for each result condition
"<method>--result<#>"            Description for each primitive result num

Notice that the "special" keys synopsis, condition<#>, and result<#> are preceded by a double dash to ensure they don't conflict with field names.

The condition keys are only required when there is more than on result type, and the result key for a given result type is only required if it's not an object.

For example, consider the 'help' command itself. There are two possible returns depending on the provided parameters. So, the help would be generated by calling the function as follows:

GenerateHelp("help", descs, (*string)(nil), (*string)(nil)).

The following keys would then be required in the provided descriptions map:

"help--synopsis":   "Returns a list of all commands or help for ...."
"help-command":     "The command to retrieve help for",
"help--condition0": "no command provided"
"help--condition1": "command specified"
"help--result0":    "List of commands"
"help--result1":    "Help for specified command"

func Int

func Int(v int) *int

Int is a helper routine that allocates a new int value to store v and returns a pointer to it. This is useful when assigning optional parameters.

func Int32

func Int32(v int32) *int32

Int32 is a helper routine that allocates a new int32 value to store v and returns a pointer to it. This is useful when assigning optional parameters.

func Int64

func Int64(v int64) *int64

Int64 is a helper routine that allocates a new int64 value to store v and returns a pointer to it. This is useful when assigning optional parameters.

func IsValidIDType

func IsValidIDType(id interface{}) bool

IsValidIDType checks that the ID field (which can go in any of the JSON-RPC requests, responses, or notifications) is valid. JSON-RPC 1.0 allows any valid JSON type. JSON-RPC 2.0 (which bitcoind follows for some parts) only allows string, number, or null, so this function restricts the allowed types to that list. This function is only provided in case the caller is manually marshalling for some reason. The functions which accept an ID in this package already call this function to ensure the provided id is valid.

func MarshalCmd

func MarshalCmd(rpcVersion string, id interface{}, cmd interface{}) ([]byte, error)

MarshalCmd marshals the passed command to a JSON-RPC request byte slice that is suitable for transmission to an RPC server. The provided command type must be a registered type. All commands provided by this package are registered by default.

Example

This example demonstrates how to create and marshal a command into a JSON-RPC request.

// 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}

func MarshalResponse

func MarshalResponse(rpcVersion string, id interface{}, result interface{}, rpcErr *RPCError) ([]byte, error)

MarshalResponse marshals the passed rpc version, id, result, and RPCError to a JSON-RPC response byte slice that is suitable for transmission to a JSON-RPC client.

Example

This example demonstrates how to marshal a JSON-RPC response.

// 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}

func MethodUsageText

func MethodUsageText(method interface{}) (string, error)

MethodUsageText returns a one-line usage string for the provided method. The provided method must be associated with a registered type. All commands provided by this package are registered by default.

func MustRegister

func MustRegister(method interface{}, cmd interface{}, flags UsageFlag)

MustRegister performs the same function as Register except it panics if there is an error. This should only be called from package init functions.

See Register for more details about correct usage.

func NewCmd

func NewCmd(method interface{}, args ...interface{}) (interface{}, error)

NewCmd provides a generic mechanism to create a new command that can marshal to a JSON-RPC request while respecting the requirements of the provided method. The method must have been registered with the package already along with its type definition. All methods associated with the commands exported by this package are already registered by default.

The arguments are most efficient when they are the exact same type as the underlying field in the command struct associated with the method, however this function also will perform a variety of conversions to make it more flexible. This allows, for example, command line args which are strings to be passed unaltered. In particular, the following conversions are supported:

  • Conversion between any size signed or unsigned integer so long as the value does not overflow the destination type
  • Conversion between float32 and float64 so long as the value does not overflow the destination type
  • Conversion from string to boolean for everything strconv.ParseBool recognizes
  • Conversion from string to any size integer for everything strconv.ParseInt and strconv.ParseUint recognizes
  • Conversion from string to any size float for everything strconv.ParseFloat recognizes
  • Conversion from string to arrays, slices, structs, and maps by treating the string as marshalled JSON and calling json.Unmarshal into the destination field

func ParseParams

func ParseParams(method interface{}, params []json.RawMessage) (interface{}, error)

ParseParams unmarshals and parses the parameters for a JSON-RPC request based on the registered method.

Example

This example demonstrates how to unmarshal a JSON-RPC request and then parse the parameters into a concrete type.

// 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

func Register

func Register(method interface{}, params interface{}, flags UsageFlag) error

Register registers a method that will automatically marshal to and from JSON-RPC with full type checking and positional parameter support. It also accepts usage flags which identify the circumstances under which the command can be used.

This package automatically registers all of the exported commands by default using this function, however it is also exported so callers can easily register custom types.

The type format is very strict since it needs to be able to automatically marshal to and from JSON-RPC 1.0. The following enumerates the requirements:

  • The method must be a string or string type
  • The provided params must be a pointer to a struct
  • All parameter fields must be exported
  • The order of the positional parameters in the marshalled JSON will be in the same order as declared in the struct definition
  • Struct embedding is not supported
  • Struct fields may NOT be channels, functions, complex, or interface
  • A field in the provided struct with a pointer is treated as optional
  • Multiple indirections (i.e **int) are not supported
  • Once the first optional field (pointer) is encountered, the remaining fields must also be optional fields (pointers) as required by positional params
  • A field that has a 'jsonrpcdefault' struct tag must be an optional field (pointer)

Duplicate registrations with identical method and params types are allowed. All other duplicate registrations of a method will error.

NOTE: This function only needs to be able to examine the structure of the passed struct, so it does not need to be an actual instance. Therefore, it is recommended to simply pass a nil pointer cast to the appropriate type. For example, (*FooCmd)(nil).

func RegisteredMethods

func RegisteredMethods(methodType interface{}) []string

RegisteredMethods returns a sorted list of methods for all registered commands.

func String

func String(v string) *string

String is a helper routine that allocates a new string value to store v and returns a pointer to it. This is useful when assigning optional parameters.

func Uint

func Uint(v uint) *uint

Uint is a helper routine that allocates a new uint value to store v and returns a pointer to it. This is useful when assigning optional parameters.

func Uint16

func Uint16(v uint16) *uint16

Uint16 is a helper routine that allocates a new uint16 value to store v and returns a pointer to it. This is useful when assigning optional parameters.

func Uint32

func Uint32(v uint32) *uint32

Uint32 is a helper routine that allocates a new uint32 value to store v and returns a pointer to it. This is useful when assigning optional parameters.

func Uint64

func Uint64(v uint64) *uint64

Uint64 is a helper routine that allocates a new uint64 value to store v and returns a pointer to it. This is useful when assigning optional parameters.

Types

type Error

type Error struct {
	Code    ErrorCode // Describes the kind of error
	Message string    // Human readable description of the issue
}

Error identifies a general error. This differs from an RPCError in that this error typically is used more by the consumers of the package as opposed to RPCErrors which are intended to be returned to the client across the wire via a JSON-RPC Response. The caller can use type assertions to determine the specific error and access the ErrorCode field.

func (Error) Error

func (e Error) Error() string

Error satisfies the error interface and prints human-readable errors.

type ErrorCode

type ErrorCode int

ErrorCode identifies a kind of error. These error codes are NOT used for JSON-RPC response errors.

const (
	// ErrDuplicateMethod indicates a command with the specified method
	// already exists.
	ErrDuplicateMethod ErrorCode = iota

	// ErrInvalidUsageFlags indicates one or more unrecognized flag bits
	// were specified.
	ErrInvalidUsageFlags

	// ErrInvalidType indicates a type was passed that is not the required
	// type.
	ErrInvalidType

	// ErrEmbeddedType indicates the provided command struct contains an
	// embedded type which is not not supported.
	ErrEmbeddedType

	// ErrUnexportedField indicates the provided command struct contains an
	// unexported field which is not supported.
	ErrUnexportedField

	// ErrUnsupportedFieldType indicates the type of a field in the provided
	// command struct is not one of the supported types.
	ErrUnsupportedFieldType

	// ErrNonOptionalField indicates a non-optional field was specified
	// after an optional field.
	ErrNonOptionalField

	// ErrNonOptionalDefault indicates a 'jsonrpcdefault' struct tag was
	// specified for a non-optional field.
	ErrNonOptionalDefault

	// ErrMismatchedDefault indicates a 'jsonrpcdefault' struct tag contains
	// a value that doesn't match the type of the field.
	ErrMismatchedDefault

	// ErrUnregisteredMethod indicates a method was specified that has not
	// been registered.
	ErrUnregisteredMethod

	// ErrMissingDescription indicates a description required to generate
	// help is missing.
	ErrMissingDescription

	// ErrNumParams indicates the number of params supplied do not
	// match the requirements of the associated command.
	ErrNumParams
)

These constants are used to identify a specific RuleError.

func (ErrorCode) String

func (e ErrorCode) String() string

String returns the ErrorCode as a human-readable name.

type RPCError

type RPCError struct {
	Code    RPCErrorCode `json:"code,omitempty"`
	Message string       `json:"message,omitempty"`
}

RPCError represents an error that is used as a part of a JSON-RPC Response object.

func NewRPCError

func NewRPCError(code RPCErrorCode, message string) *RPCError

NewRPCError constructs and returns a new JSON-RPC error that is suitable for use in a JSON-RPC Response object.

func (RPCError) Error

func (e RPCError) Error() string

Error returns a string describing the RPC error. This satisfies the builtin error interface.

type RPCErrorCode

type RPCErrorCode int

RPCErrorCode represents an error code to be used as a part of an RPCError which is in turn used in a JSON-RPC Response object.

A specific type is used to help ensure the wrong errors aren't used.

const (
	ErrRPCMisc                RPCErrorCode = -1
	ErrRPCForbiddenBySafeMode RPCErrorCode = -2
	ErrRPCType                RPCErrorCode = -3
	ErrRPCInvalidAddressOrKey RPCErrorCode = -5
	ErrRPCOutOfMemory         RPCErrorCode = -7
	ErrRPCInvalidParameter    RPCErrorCode = -8
	ErrRPCDatabase            RPCErrorCode = -20
	ErrRPCDeserialization     RPCErrorCode = -22
	ErrRPCVerify              RPCErrorCode = -25
)

General application defined JSON errors.

const (
	ErrRPCClientNotConnected      RPCErrorCode = -9
	ErrRPCClientInInitialDownload RPCErrorCode = -10
)

Peer-to-peer client errors.

const (
	ErrRPCWallet                    RPCErrorCode = -4
	ErrRPCWalletInsufficientFunds   RPCErrorCode = -6
	ErrRPCWalletInvalidAccountName  RPCErrorCode = -11
	ErrRPCWalletKeypoolRanOut       RPCErrorCode = -12
	ErrRPCWalletUnlockNeeded        RPCErrorCode = -13
	ErrRPCWalletPassphraseIncorrect RPCErrorCode = -14
	ErrRPCWalletWrongEncState       RPCErrorCode = -15
	ErrRPCWalletEncryptionFailed    RPCErrorCode = -16
	ErrRPCWalletAlreadyUnlocked     RPCErrorCode = -17
)

Wallet JSON errors

const (
	ErrRPCBlockNotFound     RPCErrorCode = -5
	ErrRPCBlockCount        RPCErrorCode = -5
	ErrRPCBestBlockHash     RPCErrorCode = -5
	ErrRPCDifficulty        RPCErrorCode = -5
	ErrRPCOutOfRange        RPCErrorCode = -1
	ErrRPCNoTxInfo          RPCErrorCode = -5
	ErrRPCNoCFIndex         RPCErrorCode = -5
	ErrRPCNoNewestBlockInfo RPCErrorCode = -5
	ErrRPCInvalidTxVout     RPCErrorCode = -5
	ErrRPCRawTxString       RPCErrorCode = -32602
	ErrRPCDecodeHexString   RPCErrorCode = -22
	ErrRPCDuplicateTx       RPCErrorCode = -40
)

Specific Errors related to commands. These are the ones a user of the RPC server are most likely to see. Generally, the codes should match one of the more general errors above.

const (
	ErrRPCNoWallet      RPCErrorCode = -1
	ErrRPCUnimplemented RPCErrorCode = -1
)

Errors that are specific to btcd.

type Request

type Request struct {
	Jsonrpc string            `json:"jsonrpc"`
	Method  string            `json:"method"`
	Params  []json.RawMessage `json:"params"`
	ID      interface{}       `json:"id"`
}

Request represents raw JSON-RPC requests. The Method field identifies the specific command type which in turn leads to different parameters. Callers typically will not use this directly since this package provides a statically typed command infrastructure which handles creation of these requests, however this struct is being exported in case the caller wants to construct raw requests for some reason.

func NewRequest

func NewRequest(rpcVersion string, id interface{}, method string, params []interface{}) (*Request, error)

NewRequest returns a new JSON-RPC request object given the provided rpc version, id, method, and parameters. The parameters are marshalled into a json.RawMessage for the Params field of the returned request object. This function is only provided in case the caller wants to construct raw requests for some reason. Typically callers will instead want to create a registered concrete command type with the NewCmd or New<Foo>Cmd functions and call the MarshalCmd function with that command to generate the marshalled JSON-RPC request.

type Response

type Response struct {
	Jsonrpc string          `json:"jsonrpc"`
	Result  json.RawMessage `json:"result"`
	Error   *RPCError       `json:"error"`
	ID      *interface{}    `json:"id"`
}

Response is the general form of a JSON-RPC response. The type of the Result field varies from one command to the next, so it is implemented as an interface. The ID field has to be a pointer to allow for a nil value when empty.

func NewResponse

func NewResponse(rpcVersion string, id interface{}, marshalledResult []byte, rpcErr *RPCError) (*Response, error)

NewResponse returns a new JSON-RPC response object given the provided rpc version, id, marshalled result, and RPC error. This function is only provided in case the caller wants to construct raw responses for some reason. Typically callers will instead want to create the fully marshalled JSON-RPC response to send over the wire with the MarshalResponse function.

type UsageFlag

type UsageFlag uint32

UsageFlag define flags that specify additional properties about the circumstances under which a command can be used.

const (

	// UFWebsocketOnly indicates that the command can only be used when
	// communicating with an RPC server over websockets.  This typically
	// applies to notifications and notification registration functions
	// since neither makes sense when using a single-shot HTTP-POST request.
	UFWebsocketOnly UsageFlag

	// UFNotification indicates that the command is actually a notification.
	// This means when it is marshalled, the ID must be nil.
	UFNotification
)

func MethodUsageFlags

func MethodUsageFlags(method interface{}) (UsageFlag, error)

MethodUsageFlags returns the usage flags for the passed command method. The provided method must be associated with a registered type. All commands provided by this package are registered by default.

func (UsageFlag) String

func (fl UsageFlag) String() string

String returns the UsageFlag in human-readable form.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL