doc.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // Copyright (c) 2015 The btcsuite developers
  2. // Use of this source code is governed by an ISC
  3. // license that can be found in the LICENSE file.
  4. /*
  5. Package btcjson provides primitives for working with the bitcoin JSON-RPC API.
  6. Overview
  7. When communicating via the JSON-RPC protocol, all of the commands need to be
  8. marshaled to and from the the wire in the appropriate format. This package
  9. provides data structures and primitives to ease this process.
  10. In addition, it also provides some additional features such as custom command
  11. registration, command categorization, and reflection-based help generation.
  12. JSON-RPC Protocol Overview
  13. This information is not necessary in order to use this package, but it does
  14. provide some intuition into what the marshaling and unmarshaling that is
  15. discussed below is doing under the hood.
  16. As defined by the JSON-RPC spec, there are effectively two forms of messages on
  17. the wire:
  18. - Request Objects
  19. {"jsonrpc":"1.0","id":"SOMEID","method":"SOMEMETHOD","params":[SOMEPARAMS]}
  20. NOTE: Notifications are the same format except the id field is null.
  21. - Response Objects
  22. {"result":SOMETHING,"error":null,"id":"SOMEID"}
  23. {"result":null,"error":{"code":SOMEINT,"message":SOMESTRING},"id":"SOMEID"}
  24. For requests, the params field can vary in what it contains depending on the
  25. method (a.k.a. command) being sent. Each parameter can be as simple as an int
  26. or a complex structure containing many nested fields. The id field is used to
  27. identify a request and will be included in the associated response.
  28. When working with asynchronous transports, such as websockets, spontaneous
  29. notifications are also possible. As indicated, they are the same as a request
  30. object, except they have the id field set to null. Therefore, servers will
  31. ignore requests with the id field set to null, while clients can choose to
  32. consume or ignore them.
  33. Unfortunately, the original Bitcoin JSON-RPC API (and hence anything compatible
  34. with it) doesn't always follow the spec and will sometimes return an error
  35. string in the result field with a null error for certain commands. However,
  36. for the most part, the error field will be set as described on failure.
  37. Marshaling and Unmarshaling
  38. Based upon the discussion above, it should be easy to see how the types of this
  39. package map into the required parts of the protocol
  40. - Request Objects (type Request)
  41. - Commands (type <Foo>Cmd)
  42. - Notifications (type <Foo>Ntfn)
  43. - Response Objects (type Response)
  44. - Result (type <Foo>Result)
  45. To simplify the marshaling of the requests and responses, the MarshalCmd and
  46. MarshalResponse functions are provided. They return the raw bytes ready to be
  47. sent across the wire.
  48. Unmarshaling a received Request object is a two step process:
  49. 1) Unmarshal the raw bytes into a Request struct instance via json.Unmarshal
  50. 2) Use UnmarshalCmd on the Result field of the unmarshaled Request to create
  51. a concrete command or notification instance with all struct fields set
  52. accordingly
  53. This approach is used since it provides the caller with access to the additional
  54. fields in the request that are not part of the command such as the ID.
  55. Unmarshaling a received Response object is also a two step process:
  56. 1) Unmarhsal the raw bytes into a Response struct instance via json.Unmarshal
  57. 2) Depending on the ID, unmarshal the Result field of the unmarshaled
  58. Response to create a concrete type instance
  59. As above, this approach is used since it provides the caller with access to the
  60. fields in the response such as the ID and Error.
  61. Command Creation
  62. This package provides two approaches for creating a new command. This first,
  63. and preferred, method is to use one of the New<Foo>Cmd functions. This allows
  64. static compile-time checking to help ensure the parameters stay in sync with
  65. the struct definitions.
  66. The second approach is the NewCmd function which takes a method (command) name
  67. and variable arguments. The function includes full checking to ensure the
  68. parameters are accurate according to provided method, however these checks are,
  69. obviously, run-time which means any mistakes won't be found until the code is
  70. actually executed. However, it is quite useful for user-supplied commands
  71. that are intentionally dynamic.
  72. Custom Command Registration
  73. The command handling of this package is built around the concept of registered
  74. commands. This is true for the wide variety of commands already provided by the
  75. package, but it also means caller can easily provide custom commands with all
  76. of the same functionality as the built-in commands. Use the RegisterCmd
  77. function for this purpose.
  78. A list of all registered methods can be obtained with the RegisteredCmdMethods
  79. function.
  80. Command Inspection
  81. All registered commands are registered with flags that identify information such
  82. as whether the command applies to a chain server, wallet server, or is a
  83. notification along with the method name to use. These flags can be obtained
  84. with the MethodUsageFlags flags, and the method can be obtained with the
  85. CmdMethod function.
  86. Help Generation
  87. To facilitate providing consistent help to users of the RPC server, this package
  88. exposes the GenerateHelp and function which uses reflection on registered
  89. commands or notifications, as well as the provided expected result types, to
  90. generate the final help text.
  91. In addition, the MethodUsageText function is provided to generate consistent
  92. one-line usage for registered commands and notifications using reflection.
  93. Errors
  94. There are 2 distinct type of errors supported by this package:
  95. - General errors related to marshaling or unmarshaling or improper use of
  96. the package (type Error)
  97. - RPC errors which are intended to be returned across the wire as a part of
  98. the JSON-RPC response (type RPCError)
  99. The first category of errors (type Error) typically indicates a programmer error
  100. and can be avoided by properly using the API. Errors of this type will be
  101. returned from the various functions available in this package. They identify
  102. issues such as unsupported field types, attempts to register malformed commands,
  103. and attempting to create a new command with an improper number of parameters.
  104. The specific reason for the error can be detected by type asserting it to a
  105. *btcjson.Error and accessing the ErrorCode field.
  106. The second category of errors (type RPCError), on the other hand, are useful for
  107. returning errors to RPC clients. Consequently, they are used in the previously
  108. described Response type.
  109. */
  110. package btcjson