1 package rpcclient
2 3 import (
4 js "encoding/json"
5 6 "github.com/p9c/p9/pkg/btcjson"
7 )
8 9 // AddNodeCommand enumerates the available commands that the AddNode function accepts.
10 type AddNodeCommand string
11 12 // Constants used to indicate the command for the AddNode function.
13 const (
14 // ANAdd indicates the specified host should be added as a persistent peer.
15 ANAdd AddNodeCommand = "add"
16 // ANRemove indicates the specified peer should be removed.
17 ANRemove AddNodeCommand = "remove"
18 // ANOneTry indicates the specified host should try to connect once, but it should not be made persistent.
19 ANOneTry AddNodeCommand = "onetry"
20 )
21 22 // String returns the AddNodeCommand in human-readable form.
23 func (cmd AddNodeCommand) String() string {
24 return string(cmd)
25 }
26 27 // FutureAddNodeResult is a future promise to deliver the result of an AddNodeAsync RPC invocation (or an applicable
28 // error).
29 type FutureAddNodeResult chan *response
30 31 // Receive waits for the response promised by the future and returns an error if any occurred when performing the
32 // specified command.
33 func (r FutureAddNodeResult) Receive() (e error) {
34 _, e = receiveFuture(r)
35 return e
36 }
37 38 // AddNodeAsync returns an instance of a type that can be used to get the result of the RPC at some future time by
39 // invoking the Receive function on the returned instance. See AddNode for the blocking version and more details.
40 func (c *Client) AddNodeAsync(host string, command AddNodeCommand) FutureAddNodeResult {
41 cmd := btcjson.NewAddNodeCmd(host, btcjson.AddNodeSubCmd(command))
42 return c.sendCmd(cmd)
43 }
44 45 // AddNode attempts to perform the passed command on the passed persistent peer. For example, it can be used to add or a
46 // remove a persistent peer, or to do a one time connection to a peer. It may not be used to remove non-persistent
47 // peers.
48 func (c *Client) AddNode(host string, command AddNodeCommand) (e error) {
49 return c.AddNodeAsync(host, command).Receive()
50 }
51 52 // FutureNodeResult is a future promise to deliver the result of a NodeAsync RPC invocation (or an applicable error).
53 type FutureNodeResult chan *response
54 55 // Receive waits for the response promised by the future and returns an error if any occurred when performing the
56 // specified command.
57 func (r FutureNodeResult) Receive() (e error) {
58 _, e = receiveFuture(r)
59 return e
60 }
61 62 // NodeAsync returns an instance of a type that can be used to get the result of the RPC at some future time by invoking
63 // the Receive function on the returned instance. See Node for the blocking version and more details.
64 func (c *Client) NodeAsync(command btcjson.NodeSubCmd, host string,
65 connectSubCmd *string,
66 ) FutureNodeResult {
67 cmd := btcjson.NewNodeCmd(command, host, connectSubCmd)
68 return c.sendCmd(cmd)
69 }
70 71 // Node attempts to perform the passed node command on the host. For example, it can be used to add or a remove a
72 // persistent peer, or to do connect or diconnect a non-persistent one. The connectSubCmd should be set either "perm" or
73 // "temp", depending on whether we are targetting a persistent or non-persistent peer. Passing nil will cause the
74 // default value to be used, which currently is "temp".
75 func (c *Client) Node(command btcjson.NodeSubCmd, host string,
76 connectSubCmd *string,
77 ) (e error) {
78 return c.NodeAsync(command, host, connectSubCmd).Receive()
79 }
80 81 // FutureGetAddedNodeInfoResult is a future promise to deliver the result of a GetAddedNodeInfoAsync RPC invocation (or
82 // an applicable error).
83 type FutureGetAddedNodeInfoResult chan *response
84 85 // Receive waits for the response promised by the future and returns information about manually added (persistent)
86 // peers.
87 func (r FutureGetAddedNodeInfoResult) Receive() ([]btcjson.GetAddedNodeInfoResult, error) {
88 res, e := receiveFuture(r)
89 if e != nil {
90 return nil, e
91 }
92 // Unmarshal as an array of getaddednodeinfo result objects.
93 var nodeInfo []btcjson.GetAddedNodeInfoResult
94 e = js.Unmarshal(res, &nodeInfo)
95 if e != nil {
96 return nil, e
97 }
98 return nodeInfo, nil
99 }
100 101 // GetAddedNodeInfoAsync returns an instance of a type that can be used to get the result of the RPC at some future time
102 // by invoking the Receive function on the returned instance. See GetAddedNodeInfo for the blocking version and more
103 // details.
104 func (c *Client) GetAddedNodeInfoAsync(peer string) FutureGetAddedNodeInfoResult {
105 cmd := btcjson.NewGetAddedNodeInfoCmd(true, &peer)
106 return c.sendCmd(cmd)
107 }
108 109 // GetAddedNodeInfo returns information about manually added (persistent) peers. See GetAddedNodeInfoNoDNS to retrieve
110 // only a list of the added (persistent) peers.
111 func (c *Client) GetAddedNodeInfo(peer string) ([]btcjson.GetAddedNodeInfoResult, error) {
112 return c.GetAddedNodeInfoAsync(peer).Receive()
113 }
114 115 // FutureGetAddedNodeInfoNoDNSResult is a future promise to deliver the result of a GetAddedNodeInfoNoDNSAsync RPC
116 // invocation (or an applicable error).
117 type FutureGetAddedNodeInfoNoDNSResult chan *response
118 119 // Receive waits for the response promised by the future and returns a list of manually added (persistent) peers.
120 func (r FutureGetAddedNodeInfoNoDNSResult) Receive() ([]string, error) {
121 res, e := receiveFuture(r)
122 if e != nil {
123 return nil, e
124 }
125 // Unmarshal result as an array of strings.
126 var nodes []string
127 e = js.Unmarshal(res, &nodes)
128 if e != nil {
129 return nil, e
130 }
131 return nodes, nil
132 }
133 134 // GetAddedNodeInfoNoDNSAsync returns an instance of a type that can be used to get the result of the RPC at some future
135 // time by invoking the Receive function on the returned instance. See GetAddedNodeInfoNoDNS for the blocking version
136 // and more details.
137 func (c *Client) GetAddedNodeInfoNoDNSAsync(peer string) FutureGetAddedNodeInfoNoDNSResult {
138 cmd := btcjson.NewGetAddedNodeInfoCmd(false, &peer)
139 return c.sendCmd(cmd)
140 }
141 142 // GetAddedNodeInfoNoDNS returns a list of manually added (persistent) peers. This works by setting the dns flag to
143 // false in the underlying RPC. See GetAddedNodeInfo to obtain more information about each added (persistent) peer.
144 func (c *Client) GetAddedNodeInfoNoDNS(peer string) ([]string, error) {
145 return c.GetAddedNodeInfoNoDNSAsync(peer).Receive()
146 }
147 148 // FutureGetConnectionCountResult is a future promise to deliver the result of a GetConnectionCountAsync RPC invocation
149 // (or an applicable error).
150 type FutureGetConnectionCountResult chan *response
151 152 // Receive waits for the response promised by the future and returns the number of active connections to other peers.
153 func (r FutureGetConnectionCountResult) Receive() (int64, error) {
154 res, e := receiveFuture(r)
155 if e != nil {
156 return 0, e
157 }
158 // Unmarshal result as an int64.
159 var count int64
160 e = js.Unmarshal(res, &count)
161 if e != nil {
162 return 0, e
163 }
164 return count, nil
165 }
166 167 // GetConnectionCountAsync returns an instance of a type that can be used to get the result of the RPC at some future
168 // time by invoking the Receive function on the returned instance. See GetConnectionCount for the blocking version and
169 // more details.
170 func (c *Client) GetConnectionCountAsync() FutureGetConnectionCountResult {
171 cmd := btcjson.NewGetConnectionCountCmd()
172 return c.sendCmd(cmd)
173 }
174 175 // GetConnectionCount returns the number of active connections to other peers.
176 func (c *Client) GetConnectionCount() (int64, error) {
177 return c.GetConnectionCountAsync().Receive()
178 }
179 180 // FuturePingResult is a future promise to deliver the result of a PingAsync RPC invocation (or an applicable error).
181 type FuturePingResult chan *response
182 183 // Receive waits for the response promised by the future and returns the result of queueing a ping to be sent to each
184 // connected peer.
185 func (r FuturePingResult) Receive() (e error) {
186 _, e = receiveFuture(r)
187 return e
188 }
189 190 // PingAsync returns an instance of a type that can be used to get the result of the RPC at some future time by invoking
191 // the Receive function on the returned instance. See Ping for the blocking version and more details.
192 func (c *Client) PingAsync() FuturePingResult {
193 cmd := btcjson.NewPingCmd()
194 return c.sendCmd(cmd)
195 }
196 197 // Ping queues a ping to be sent to each connected peer. Use the GetPeerInfo function and examine the PingTime and
198 // PingWait fields to access the ping times.
199 func (c *Client) Ping() (e error) {
200 return c.PingAsync().Receive()
201 }
202 203 // FutureGetPeerInfoResult is a future promise to deliver the result of a GetPeerInfoAsync RPC invocation (or an
204 // applicable error).
205 type FutureGetPeerInfoResult chan *response
206 207 // Receive waits for the response promised by the future and returns data about each connected network peer.
208 func (r FutureGetPeerInfoResult) Receive() ([]btcjson.GetPeerInfoResult, error) {
209 res, e := receiveFuture(r)
210 if e != nil {
211 return nil, e
212 }
213 // Unmarshal result as an array of getpeerinfo result objects.
214 var peerInfo []btcjson.GetPeerInfoResult
215 e = js.Unmarshal(res, &peerInfo)
216 if e != nil {
217 return nil, e
218 }
219 return peerInfo, nil
220 }
221 222 // GetPeerInfoAsync returns an instance of a type that can be used to get the result of the RPC at some future time by
223 // invoking the Receive function on the returned instance.
224 //
225 // See GetPeerInfo for the blocking version and more details.
226 func (c *Client) GetPeerInfoAsync() FutureGetPeerInfoResult {
227 cmd := btcjson.NewGetPeerInfoCmd()
228 return c.sendCmd(cmd)
229 }
230 231 // GetPeerInfo returns data about each connected network peer.
232 func (c *Client) GetPeerInfo() ([]btcjson.GetPeerInfoResult, error) {
233 return c.GetPeerInfoAsync().Receive()
234 }
235 236 // FutureGetNetTotalsResult is a future promise to deliver the result of a GetNetTotalsAsync RPC invocation (or an
237 // applicable error).
238 type FutureGetNetTotalsResult chan *response
239 240 // Receive waits for the response promised by the future and returns network statistics.
241 func (r FutureGetNetTotalsResult) Receive() (*btcjson.GetNetTotalsResult, error) {
242 res, e := receiveFuture(r)
243 if e != nil {
244 return nil, e
245 }
246 // Unmarshal result as a getnettotals result object.
247 var totals btcjson.GetNetTotalsResult
248 e = js.Unmarshal(res, &totals)
249 if e != nil {
250 return nil, e
251 }
252 return &totals, nil
253 }
254 255 // GetNetTotalsAsync returns an instance of a type that can be used to get the result of the RPC at some future time by
256 // invoking the Receive function on the returned instance.
257 //
258 // See GetNetTotals for the blocking version and more details.
259 func (c *Client) GetNetTotalsAsync() FutureGetNetTotalsResult {
260 cmd := btcjson.NewGetNetTotalsCmd()
261 return c.sendCmd(cmd)
262 }
263 264 // GetNetTotals returns network traffic statistics.
265 func (c *Client) GetNetTotals() (*btcjson.GetNetTotalsResult, error) {
266 return c.GetNetTotalsAsync().Receive()
267 }
268