chainsvrcmds_test.go raw
1 package btcjson_test
2
3 import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "reflect"
8 "testing"
9
10 "github.com/p9c/p9/pkg/btcjson"
11 "github.com/p9c/p9/pkg/wire"
12 )
13
14 // TestChainSvrCmds tests all of the chain server commands marshal and unmarshal into valid results include handling of
15 // optional fields being omitted in the marshalled command, while optional fields with defaults have the default
16 // assigned on unmarshalled commands.
17 func TestChainSvrCmds(t *testing.T) {
18 t.Parallel()
19 testID := 1
20 tests := []struct {
21 name string
22 newCmd func() (interface{}, error)
23 staticCmd func() interface{}
24 marshalled string
25 unmarshalled interface{}
26 }{
27 {
28 name: "addnode",
29 newCmd: func() (interface{}, error) {
30 return btcjson.NewCmd("addnode", "127.0.0.1", btcjson.ANRemove)
31 },
32 staticCmd: func() interface{} {
33 return btcjson.NewAddNodeCmd("127.0.0.1", btcjson.ANRemove)
34 },
35 marshalled: `{"jsonrpc":"1.0","method":"addnode","netparams":["127.0.0.1","remove"],"id":1}`,
36 unmarshalled: &btcjson.AddNodeCmd{Addr: "127.0.0.1", SubCmd: btcjson.ANRemove},
37 },
38 {
39 name: "createrawtransaction",
40 newCmd: func() (interface{}, error) {
41 return btcjson.NewCmd(
42 "createrawtransaction", `[{"txid":"123","vout":1}]`,
43 `{"456":0.0123}`,
44 )
45 },
46 staticCmd: func() interface{} {
47 txInputs := []btcjson.TransactionInput{
48 {Txid: "123", Vout: 1},
49 }
50 amounts := map[string]float64{"456": .0123}
51 return btcjson.NewCreateRawTransactionCmd(txInputs, amounts, nil)
52 },
53 marshalled: `{"jsonrpc":"1.0","method":"createrawtransaction","netparams":[[{"txid":"123","vout":1}],{"456":0.0123}],"id":1}`,
54 unmarshalled: &btcjson.CreateRawTransactionCmd{
55 Inputs: []btcjson.TransactionInput{{Txid: "123", Vout: 1}},
56 Amounts: map[string]float64{"456": .0123},
57 },
58 },
59 {
60 name: "createrawtransaction optional",
61 newCmd: func() (interface{}, error) {
62 return btcjson.NewCmd(
63 "createrawtransaction", `[{"txid":"123","vout":1}]`,
64 `{"456":0.0123}`, int64(12312333333),
65 )
66 },
67 staticCmd: func() interface{} {
68 txInputs := []btcjson.TransactionInput{
69 {Txid: "123", Vout: 1},
70 }
71 amounts := map[string]float64{"456": .0123}
72 return btcjson.NewCreateRawTransactionCmd(txInputs, amounts, btcjson.Int64(12312333333))
73 },
74 marshalled: `{"jsonrpc":"1.0","method":"createrawtransaction","netparams":[[{"txid":"123","vout":1}],{"456":0.0123},12312333333],"id":1}`,
75 unmarshalled: &btcjson.CreateRawTransactionCmd{
76 Inputs: []btcjson.TransactionInput{{Txid: "123", Vout: 1}},
77 Amounts: map[string]float64{"456": .0123},
78 LockTime: btcjson.Int64(12312333333),
79 },
80 },
81 {
82 name: "decoderawtransaction",
83 newCmd: func() (interface{}, error) {
84 return btcjson.NewCmd("decoderawtransaction", "123")
85 },
86 staticCmd: func() interface{} {
87 return btcjson.NewDecodeRawTransactionCmd("123")
88 },
89 marshalled: `{"jsonrpc":"1.0","method":"decoderawtransaction","netparams":["123"],"id":1}`,
90 unmarshalled: &btcjson.DecodeRawTransactionCmd{HexTx: "123"},
91 },
92 {
93 name: "decodescript",
94 newCmd: func() (interface{}, error) {
95 return btcjson.NewCmd("decodescript", "00")
96 },
97 staticCmd: func() interface{} {
98 return btcjson.NewDecodeScriptCmd("00")
99 },
100 marshalled: `{"jsonrpc":"1.0","method":"decodescript","netparams":["00"],"id":1}`,
101 unmarshalled: &btcjson.DecodeScriptCmd{HexScript: "00"},
102 },
103 {
104 name: "getaddednodeinfo",
105 newCmd: func() (interface{}, error) {
106 return btcjson.NewCmd("getaddednodeinfo", true)
107 },
108 staticCmd: func() interface{} {
109 return btcjson.NewGetAddedNodeInfoCmd(true, nil)
110 },
111 marshalled: `{"jsonrpc":"1.0","method":"getaddednodeinfo","netparams":[true],"id":1}`,
112 unmarshalled: &btcjson.GetAddedNodeInfoCmd{DNS: true, Node: nil},
113 },
114 {
115 name: "getaddednodeinfo optional",
116 newCmd: func() (interface{}, error) {
117 return btcjson.NewCmd("getaddednodeinfo", true, "127.0.0.1")
118 },
119 staticCmd: func() interface{} {
120 return btcjson.NewGetAddedNodeInfoCmd(true, btcjson.String("127.0.0.1"))
121 },
122 marshalled: `{"jsonrpc":"1.0","method":"getaddednodeinfo","netparams":[true,"127.0.0.1"],"id":1}`,
123 unmarshalled: &btcjson.GetAddedNodeInfoCmd{
124 DNS: true,
125 Node: btcjson.String("127.0.0.1"),
126 },
127 },
128 {
129 name: "getbestblockhash",
130 newCmd: func() (interface{}, error) {
131 return btcjson.NewCmd("getbestblockhash")
132 },
133 staticCmd: func() interface{} {
134 return btcjson.NewGetBestBlockHashCmd()
135 },
136 marshalled: `{"jsonrpc":"1.0","method":"getbestblockhash","netparams":[],"id":1}`,
137 unmarshalled: &btcjson.GetBestBlockHashCmd{},
138 },
139 {
140 name: "getblock",
141 newCmd: func() (interface{}, error) {
142 return btcjson.NewCmd("getblock", "123")
143 },
144 staticCmd: func() interface{} {
145 return btcjson.NewGetBlockCmd("123", nil, nil)
146 },
147 marshalled: `{"jsonrpc":"1.0","method":"getblock","netparams":["123"],"id":1}`,
148 unmarshalled: &btcjson.GetBlockCmd{
149 Hash: "123",
150 Verbose: btcjson.Bool(true),
151 VerboseTx: btcjson.Bool(false),
152 },
153 },
154 {
155 name: "getblock required optional1",
156 newCmd: func() (interface{}, error) {
157 // Intentionally use a source param that is more pointers than the destination to exercise that path.
158 verbosePtr := btcjson.Bool(true)
159 return btcjson.NewCmd("getblock", "123", &verbosePtr)
160 },
161 staticCmd: func() interface{} {
162 return btcjson.NewGetBlockCmd("123", btcjson.Bool(true), nil)
163 },
164 marshalled: `{"jsonrpc":"1.0","method":"getblock","netparams":["123",true],"id":1}`,
165 unmarshalled: &btcjson.GetBlockCmd{
166 Hash: "123",
167 Verbose: btcjson.Bool(true),
168 VerboseTx: btcjson.Bool(false),
169 },
170 },
171 {
172 name: "getblock required optional2",
173 newCmd: func() (interface{}, error) {
174 return btcjson.NewCmd("getblock", "123", true, true)
175 },
176 staticCmd: func() interface{} {
177 return btcjson.NewGetBlockCmd("123", btcjson.Bool(true), btcjson.Bool(true))
178 },
179 marshalled: `{"jsonrpc":"1.0","method":"getblock","netparams":["123",true,true],"id":1}`,
180 unmarshalled: &btcjson.GetBlockCmd{
181 Hash: "123",
182 Verbose: btcjson.Bool(true),
183 VerboseTx: btcjson.Bool(true),
184 },
185 },
186 {
187 name: "getblockchaininfo",
188 newCmd: func() (interface{}, error) {
189 return btcjson.NewCmd("getblockchaininfo")
190 },
191 staticCmd: func() interface{} {
192 return btcjson.NewGetBlockChainInfoCmd()
193 },
194 marshalled: `{"jsonrpc":"1.0","method":"getblockchaininfo","netparams":[],"id":1}`,
195 unmarshalled: &btcjson.GetBlockChainInfoCmd{},
196 },
197 {
198 name: "getblockcount",
199 newCmd: func() (interface{}, error) {
200 return btcjson.NewCmd("getblockcount")
201 },
202 staticCmd: func() interface{} {
203 return btcjson.NewGetBlockCountCmd()
204 },
205 marshalled: `{"jsonrpc":"1.0","method":"getblockcount","netparams":[],"id":1}`,
206 unmarshalled: &btcjson.GetBlockCountCmd{},
207 },
208 {
209 name: "getblockhash",
210 newCmd: func() (interface{}, error) {
211 return btcjson.NewCmd("getblockhash", 123)
212 },
213 staticCmd: func() interface{} {
214 return btcjson.NewGetBlockHashCmd(123)
215 },
216 marshalled: `{"jsonrpc":"1.0","method":"getblockhash","netparams":[123],"id":1}`,
217 unmarshalled: &btcjson.GetBlockHashCmd{Index: 123},
218 },
219 {
220 name: "getblockheader",
221 newCmd: func() (interface{}, error) {
222 return btcjson.NewCmd("getblockheader", "123")
223 },
224 staticCmd: func() interface{} {
225 return btcjson.NewGetBlockHeaderCmd("123", nil)
226 },
227 marshalled: `{"jsonrpc":"1.0","method":"getblockheader","netparams":["123"],"id":1}`,
228 unmarshalled: &btcjson.GetBlockHeaderCmd{
229 Hash: "123",
230 Verbose: btcjson.Bool(true),
231 },
232 },
233 {
234 name: "getblocktemplate",
235 newCmd: func() (interface{}, error) {
236 return btcjson.NewCmd("getblocktemplate")
237 },
238 staticCmd: func() interface{} {
239 return btcjson.NewGetBlockTemplateCmd(nil)
240 },
241 marshalled: `{"jsonrpc":"1.0","method":"getblocktemplate","netparams":[],"id":1}`,
242 unmarshalled: &btcjson.GetBlockTemplateCmd{Request: nil},
243 },
244 {
245 name: "getblocktemplate optional - template request",
246 newCmd: func() (interface{}, error) {
247 return btcjson.NewCmd(
248 "getblocktemplate",
249 `{"mode":"template","capabilities":["longpoll","coinbasetxn"]}`,
250 )
251 },
252 staticCmd: func() interface{} {
253 template := btcjson.TemplateRequest{
254 Mode: "template",
255 Capabilities: []string{"longpoll", "coinbasetxn"},
256 }
257 return btcjson.NewGetBlockTemplateCmd(&template)
258 },
259 marshalled: `{"jsonrpc":"1.0","method":"getblocktemplate","netparams":[{"mode":"template","capabilities":["longpoll","coinbasetxn"]}],"id":1}`,
260 unmarshalled: &btcjson.GetBlockTemplateCmd{
261 Request: &btcjson.TemplateRequest{
262 Mode: "template",
263 Capabilities: []string{"longpoll", "coinbasetxn"},
264 },
265 },
266 },
267 {
268 name: "getblocktemplate optional - template request with tweaks",
269 newCmd: func() (interface{}, error) {
270 return btcjson.NewCmd(
271 "getblocktemplate",
272 `{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":500,"sizelimit":100000000,"maxversion":2}`,
273 )
274 },
275 staticCmd: func() interface{} {
276 template := btcjson.TemplateRequest{
277 Mode: "template",
278 Capabilities: []string{"longpoll", "coinbasetxn"},
279 SigOpLimit: 500,
280 SizeLimit: 100000000,
281 MaxVersion: 2,
282 }
283 return btcjson.NewGetBlockTemplateCmd(&template)
284 },
285 marshalled: `{"jsonrpc":"1.0","method":"getblocktemplate","netparams":[{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":500,"sizelimit":100000000,"maxversion":2}],"id":1}`,
286 unmarshalled: &btcjson.GetBlockTemplateCmd{
287 Request: &btcjson.TemplateRequest{
288 Mode: "template",
289 Capabilities: []string{"longpoll", "coinbasetxn"},
290 SigOpLimit: int64(500),
291 SizeLimit: int64(100000000),
292 MaxVersion: 2,
293 },
294 },
295 },
296 {
297 name: "getblocktemplate optional - template request with tweaks 2",
298 newCmd: func() (interface{}, error) {
299 return btcjson.NewCmd(
300 "getblocktemplate",
301 `{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":true,"sizelimit":100000000,"maxversion":2}`,
302 )
303 },
304 staticCmd: func() interface{} {
305 template := btcjson.TemplateRequest{
306 Mode: "template",
307 Capabilities: []string{"longpoll", "coinbasetxn"},
308 SigOpLimit: true,
309 SizeLimit: 100000000,
310 MaxVersion: 2,
311 }
312 return btcjson.NewGetBlockTemplateCmd(&template)
313 },
314 marshalled: `{"jsonrpc":"1.0","method":"getblocktemplate","netparams":[{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":true,"sizelimit":100000000,"maxversion":2}],"id":1}`,
315 unmarshalled: &btcjson.GetBlockTemplateCmd{
316 Request: &btcjson.TemplateRequest{
317 Mode: "template",
318 Capabilities: []string{"longpoll", "coinbasetxn"},
319 SigOpLimit: true,
320 SizeLimit: int64(100000000),
321 MaxVersion: 2,
322 },
323 },
324 },
325 {
326 name: "getcfilter",
327 newCmd: func() (interface{}, error) {
328 return btcjson.NewCmd(
329 "getcfilter", "123",
330 wire.GCSFilterRegular,
331 )
332 },
333 staticCmd: func() interface{} {
334 return btcjson.NewGetCFilterCmd(
335 "123",
336 wire.GCSFilterRegular,
337 )
338 },
339 marshalled: `{"jsonrpc":"1.0","method":"getcfilter","netparams":["123",0],"id":1}`,
340 unmarshalled: &btcjson.GetCFilterCmd{
341 Hash: "123",
342 FilterType: wire.GCSFilterRegular,
343 },
344 },
345 {
346 name: "getcfilterheader",
347 newCmd: func() (interface{}, error) {
348 return btcjson.NewCmd(
349 "getcfilterheader", "123",
350 wire.GCSFilterRegular,
351 )
352 },
353 staticCmd: func() interface{} {
354 return btcjson.NewGetCFilterHeaderCmd(
355 "123",
356 wire.GCSFilterRegular,
357 )
358 },
359 marshalled: `{"jsonrpc":"1.0","method":"getcfilterheader","netparams":["123",0],"id":1}`,
360 unmarshalled: &btcjson.GetCFilterHeaderCmd{
361 Hash: "123",
362 FilterType: wire.GCSFilterRegular,
363 },
364 },
365 {
366 name: "getchaintips",
367 newCmd: func() (interface{}, error) {
368 return btcjson.NewCmd("getchaintips")
369 },
370 staticCmd: func() interface{} {
371 return btcjson.NewGetChainTipsCmd()
372 },
373 marshalled: `{"jsonrpc":"1.0","method":"getchaintips","netparams":[],"id":1}`,
374 unmarshalled: &btcjson.GetChainTipsCmd{},
375 },
376 {
377 name: "getconnectioncount",
378 newCmd: func() (interface{}, error) {
379 return btcjson.NewCmd("getconnectioncount")
380 },
381 staticCmd: func() interface{} {
382 return btcjson.NewGetConnectionCountCmd()
383 },
384 marshalled: `{"jsonrpc":"1.0","method":"getconnectioncount","netparams":[],"id":1}`,
385 unmarshalled: &btcjson.GetConnectionCountCmd{},
386 },
387 {
388 name: "getdifficulty",
389 newCmd: func() (interface{}, error) {
390 return btcjson.NewCmd("getdifficulty", "123")
391 },
392 staticCmd: func() interface{} {
393 return btcjson.NewGetDifficultyCmd("123")
394 },
395 marshalled: `{"jsonrpc":"1.0","method":"getdifficulty","netparams":["123"],"id":1}`,
396 unmarshalled: &btcjson.GetDifficultyCmd{Algo: "123"},
397 },
398 {
399 name: "getgenerate",
400 newCmd: func() (interface{}, error) {
401 return btcjson.NewCmd("getgenerate")
402 },
403 staticCmd: func() interface{} {
404 return btcjson.NewGetGenerateCmd()
405 },
406 marshalled: `{"jsonrpc":"1.0","method":"getgenerate","netparams":[],"id":1}`,
407 unmarshalled: &btcjson.GetGenerateCmd{},
408 },
409 {
410 name: "gethashespersec",
411 newCmd: func() (interface{}, error) {
412 return btcjson.NewCmd("gethashespersec")
413 },
414 staticCmd: func() interface{} {
415 return btcjson.NewGetHashesPerSecCmd()
416 },
417 marshalled: `{"jsonrpc":"1.0","method":"gethashespersec","netparams":[],"id":1}`,
418 unmarshalled: &btcjson.GetHashesPerSecCmd{},
419 },
420 {
421 name: "getinfo",
422 newCmd: func() (interface{}, error) {
423 return btcjson.NewCmd("getinfo")
424 },
425 staticCmd: func() interface{} {
426 return btcjson.NewGetInfoCmd()
427 },
428 marshalled: `{"jsonrpc":"1.0","method":"getinfo","netparams":[],"id":1}`,
429 unmarshalled: &btcjson.GetInfoCmd{},
430 },
431 {
432 name: "getmempoolentry",
433 newCmd: func() (interface{}, error) {
434 return btcjson.NewCmd("getmempoolentry", "txhash")
435 },
436 staticCmd: func() interface{} {
437 return btcjson.NewGetMempoolEntryCmd("txhash")
438 },
439 marshalled: `{"jsonrpc":"1.0","method":"getmempoolentry","netparams":["txhash"],"id":1}`,
440 unmarshalled: &btcjson.GetMempoolEntryCmd{
441 TxID: "txhash",
442 },
443 },
444 {
445 name: "getmempoolinfo",
446 newCmd: func() (interface{}, error) {
447 return btcjson.NewCmd("getmempoolinfo")
448 },
449 staticCmd: func() interface{} {
450 return btcjson.NewGetMempoolInfoCmd()
451 },
452 marshalled: `{"jsonrpc":"1.0","method":"getmempoolinfo","netparams":[],"id":1}`,
453 unmarshalled: &btcjson.GetMempoolInfoCmd{},
454 },
455 {
456 name: "getmininginfo",
457 newCmd: func() (interface{}, error) {
458 return btcjson.NewCmd("getmininginfo")
459 },
460 staticCmd: func() interface{} {
461 return btcjson.NewGetMiningInfoCmd()
462 },
463 marshalled: `{"jsonrpc":"1.0","method":"getmininginfo","netparams":[],"id":1}`,
464 unmarshalled: &btcjson.GetMiningInfoCmd{},
465 },
466 {
467 name: "getnetworkinfo",
468 newCmd: func() (interface{}, error) {
469 return btcjson.NewCmd("getnetworkinfo")
470 },
471 staticCmd: func() interface{} {
472 return btcjson.NewGetNetworkInfoCmd()
473 },
474 marshalled: `{"jsonrpc":"1.0","method":"getnetworkinfo","netparams":[],"id":1}`,
475 unmarshalled: &btcjson.GetNetworkInfoCmd{},
476 },
477 {
478 name: "getnettotals",
479 newCmd: func() (interface{}, error) {
480 return btcjson.NewCmd("getnettotals")
481 },
482 staticCmd: func() interface{} {
483 return btcjson.NewGetNetTotalsCmd()
484 },
485 marshalled: `{"jsonrpc":"1.0","method":"getnettotals","netparams":[],"id":1}`,
486 unmarshalled: &btcjson.GetNetTotalsCmd{},
487 },
488 {
489 name: "getnetworkhashps",
490 newCmd: func() (interface{}, error) {
491 return btcjson.NewCmd("getnetworkhashps")
492 },
493 staticCmd: func() interface{} {
494 return btcjson.NewGetNetworkHashPSCmd(nil, nil)
495 },
496 marshalled: `{"jsonrpc":"1.0","method":"getnetworkhashps","netparams":[],"id":1}`,
497 unmarshalled: &btcjson.GetNetworkHashPSCmd{
498 Blocks: btcjson.Int(120),
499 Height: btcjson.Int(-1),
500 },
501 },
502 {
503 name: "getnetworkhashps optional1",
504 newCmd: func() (interface{}, error) {
505 return btcjson.NewCmd("getnetworkhashps", 200)
506 },
507 staticCmd: func() interface{} {
508 return btcjson.NewGetNetworkHashPSCmd(btcjson.Int(200), nil)
509 },
510 marshalled: `{"jsonrpc":"1.0","method":"getnetworkhashps","netparams":[200],"id":1}`,
511 unmarshalled: &btcjson.GetNetworkHashPSCmd{
512 Blocks: btcjson.Int(200),
513 Height: btcjson.Int(-1),
514 },
515 },
516 {
517 name: "getnetworkhashps optional2",
518 newCmd: func() (interface{}, error) {
519 return btcjson.NewCmd("getnetworkhashps", 200, 123)
520 },
521 staticCmd: func() interface{} {
522 return btcjson.NewGetNetworkHashPSCmd(btcjson.Int(200), btcjson.Int(123))
523 },
524 marshalled: `{"jsonrpc":"1.0","method":"getnetworkhashps","netparams":[200,123],"id":1}`,
525 unmarshalled: &btcjson.GetNetworkHashPSCmd{
526 Blocks: btcjson.Int(200),
527 Height: btcjson.Int(123),
528 },
529 },
530 {
531 name: "getpeerinfo",
532 newCmd: func() (interface{}, error) {
533 return btcjson.NewCmd("getpeerinfo")
534 },
535 staticCmd: func() interface{} {
536 return btcjson.NewGetPeerInfoCmd()
537 },
538 marshalled: `{"jsonrpc":"1.0","method":"getpeerinfo","netparams":[],"id":1}`,
539 unmarshalled: &btcjson.GetPeerInfoCmd{},
540 },
541 {
542 name: "getrawmempool",
543 newCmd: func() (interface{}, error) {
544 return btcjson.NewCmd("getrawmempool")
545 },
546 staticCmd: func() interface{} {
547 return btcjson.NewGetRawMempoolCmd(nil)
548 },
549 marshalled: `{"jsonrpc":"1.0","method":"getrawmempool","netparams":[],"id":1}`,
550 unmarshalled: &btcjson.GetRawMempoolCmd{
551 Verbose: btcjson.Bool(false),
552 },
553 },
554 {
555 name: "getrawmempool optional",
556 newCmd: func() (interface{}, error) {
557 return btcjson.NewCmd("getrawmempool", false)
558 },
559 staticCmd: func() interface{} {
560 return btcjson.NewGetRawMempoolCmd(btcjson.Bool(false))
561 },
562 marshalled: `{"jsonrpc":"1.0","method":"getrawmempool","netparams":[false],"id":1}`,
563 unmarshalled: &btcjson.GetRawMempoolCmd{
564 Verbose: btcjson.Bool(false),
565 },
566 },
567 {
568 name: "getrawtransaction",
569 newCmd: func() (interface{}, error) {
570 return btcjson.NewCmd("getrawtransaction", "123")
571 },
572 staticCmd: func() interface{} {
573 return btcjson.NewGetRawTransactionCmd("123", nil)
574 },
575 marshalled: `{"jsonrpc":"1.0","method":"getrawtransaction","netparams":["123"],"id":1}`,
576 unmarshalled: &btcjson.GetRawTransactionCmd{
577 Txid: "123",
578 Verbose: btcjson.Int(0),
579 },
580 },
581 {
582 name: "getrawtransaction optional",
583 newCmd: func() (interface{}, error) {
584 return btcjson.NewCmd("getrawtransaction", "123", 1)
585 },
586 staticCmd: func() interface{} {
587 return btcjson.NewGetRawTransactionCmd("123", btcjson.Int(1))
588 },
589 marshalled: `{"jsonrpc":"1.0","method":"getrawtransaction","netparams":["123",1],"id":1}`,
590 unmarshalled: &btcjson.GetRawTransactionCmd{
591 Txid: "123",
592 Verbose: btcjson.Int(1),
593 },
594 },
595 {
596 name: "gettxout",
597 newCmd: func() (interface{}, error) {
598 return btcjson.NewCmd("gettxout", "123", 1)
599 },
600 staticCmd: func() interface{} {
601 return btcjson.NewGetTxOutCmd("123", 1, nil)
602 },
603 marshalled: `{"jsonrpc":"1.0","method":"gettxout","netparams":["123",1],"id":1}`,
604 unmarshalled: &btcjson.GetTxOutCmd{
605 Txid: "123",
606 Vout: 1,
607 IncludeMempool: btcjson.Bool(true),
608 },
609 },
610 {
611 name: "gettxout optional",
612 newCmd: func() (interface{}, error) {
613 return btcjson.NewCmd("gettxout", "123", 1, true)
614 },
615 staticCmd: func() interface{} {
616 return btcjson.NewGetTxOutCmd("123", 1, btcjson.Bool(true))
617 },
618 marshalled: `{"jsonrpc":"1.0","method":"gettxout","netparams":["123",1,true],"id":1}`,
619 unmarshalled: &btcjson.GetTxOutCmd{
620 Txid: "123",
621 Vout: 1,
622 IncludeMempool: btcjson.Bool(true),
623 },
624 },
625 {
626 name: "gettxoutproof",
627 newCmd: func() (interface{}, error) {
628 return btcjson.NewCmd("gettxoutproof", []string{"123", "456"})
629 },
630 staticCmd: func() interface{} {
631 return btcjson.NewGetTxOutProofCmd([]string{"123", "456"}, nil)
632 },
633 marshalled: `{"jsonrpc":"1.0","method":"gettxoutproof","netparams":[["123","456"]],"id":1}`,
634 unmarshalled: &btcjson.GetTxOutProofCmd{
635 TxIDs: []string{"123", "456"},
636 },
637 },
638 {
639 name: "gettxoutproof optional",
640 newCmd: func() (interface{}, error) {
641 return btcjson.NewCmd(
642 "gettxoutproof", []string{"123", "456"},
643 btcjson.String("000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf"),
644 )
645 },
646 staticCmd: func() interface{} {
647 return btcjson.NewGetTxOutProofCmd(
648 []string{"123", "456"},
649 btcjson.String("000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf"),
650 )
651 },
652 marshalled: `{"jsonrpc":"1.0","method":"gettxoutproof","netparams":[["123","456"],` +
653 `"000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf"],"id":1}`,
654 unmarshalled: &btcjson.GetTxOutProofCmd{
655 TxIDs: []string{"123", "456"},
656 BlockHash: btcjson.String("000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf"),
657 },
658 },
659 {
660 name: "gettxoutsetinfo",
661 newCmd: func() (interface{}, error) {
662 return btcjson.NewCmd("gettxoutsetinfo")
663 },
664 staticCmd: func() interface{} {
665 return btcjson.NewGetTxOutSetInfoCmd()
666 },
667 marshalled: `{"jsonrpc":"1.0","method":"gettxoutsetinfo","netparams":[],"id":1}`,
668 unmarshalled: &btcjson.GetTxOutSetInfoCmd{},
669 },
670 {
671 name: "getwork",
672 newCmd: func() (interface{}, error) {
673 return btcjson.NewCmd("getwork")
674 },
675 staticCmd: func() interface{} {
676 return btcjson.NewGetWorkCmd(nil)
677 },
678 marshalled: `{"jsonrpc":"1.0","method":"getwork","netparams":[],"id":1}`,
679 unmarshalled: &btcjson.GetWorkCmd{
680 Data: nil,
681 },
682 },
683 {
684 name: "getwork optional",
685 newCmd: func() (interface{}, error) {
686 return btcjson.NewCmd("getwork", "00112233")
687 },
688 staticCmd: func() interface{} {
689 return btcjson.NewGetWorkCmd(btcjson.String("00112233"))
690 },
691 marshalled: `{"jsonrpc":"1.0","method":"getwork","netparams":["00112233"],"id":1}`,
692 unmarshalled: &btcjson.GetWorkCmd{
693 Data: btcjson.String("00112233"),
694 },
695 },
696 {
697 name: "help",
698 newCmd: func() (interface{}, error) {
699 return btcjson.NewCmd("help")
700 },
701 staticCmd: func() interface{} {
702 return btcjson.NewHelpCmd(nil)
703 },
704 marshalled: `{"jsonrpc":"1.0","method":"help","netparams":[],"id":1}`,
705 unmarshalled: &btcjson.HelpCmd{
706 Command: nil,
707 },
708 },
709 {
710 name: "help optional",
711 newCmd: func() (interface{}, error) {
712 return btcjson.NewCmd("help", "getblock")
713 },
714 staticCmd: func() interface{} {
715 return btcjson.NewHelpCmd(btcjson.String("getblock"))
716 },
717 marshalled: `{"jsonrpc":"1.0","method":"help","netparams":["getblock"],"id":1}`,
718 unmarshalled: &btcjson.HelpCmd{
719 Command: btcjson.String("getblock"),
720 },
721 },
722 {
723 name: "invalidateblock",
724 newCmd: func() (interface{}, error) {
725 return btcjson.NewCmd("invalidateblock", "123")
726 },
727 staticCmd: func() interface{} {
728 return btcjson.NewInvalidateBlockCmd("123")
729 },
730 marshalled: `{"jsonrpc":"1.0","method":"invalidateblock","netparams":["123"],"id":1}`,
731 unmarshalled: &btcjson.InvalidateBlockCmd{
732 BlockHash: "123",
733 },
734 },
735 {
736 name: "ping",
737 newCmd: func() (interface{}, error) {
738 return btcjson.NewCmd("ping")
739 },
740 staticCmd: func() interface{} {
741 return btcjson.NewPingCmd()
742 },
743 marshalled: `{"jsonrpc":"1.0","method":"ping","netparams":[],"id":1}`,
744 unmarshalled: &btcjson.PingCmd{},
745 },
746 {
747 name: "preciousblock",
748 newCmd: func() (interface{}, error) {
749 return btcjson.NewCmd("preciousblock", "0123")
750 },
751 staticCmd: func() interface{} {
752 return btcjson.NewPreciousBlockCmd("0123")
753 },
754 marshalled: `{"jsonrpc":"1.0","method":"preciousblock","netparams":["0123"],"id":1}`,
755 unmarshalled: &btcjson.PreciousBlockCmd{
756 BlockHash: "0123",
757 },
758 },
759 {
760 name: "reconsiderblock",
761 newCmd: func() (interface{}, error) {
762 return btcjson.NewCmd("reconsiderblock", "123")
763 },
764 staticCmd: func() interface{} {
765 return btcjson.NewReconsiderBlockCmd("123")
766 },
767 marshalled: `{"jsonrpc":"1.0","method":"reconsiderblock","netparams":["123"],"id":1}`,
768 unmarshalled: &btcjson.ReconsiderBlockCmd{
769 BlockHash: "123",
770 },
771 },
772 {
773 name: "searchrawtransactions",
774 newCmd: func() (interface{}, error) {
775 return btcjson.NewCmd("searchrawtransactions", "1Address")
776 },
777 staticCmd: func() interface{} {
778 return btcjson.NewSearchRawTransactionsCmd("1Address", nil, nil, nil, nil, nil, nil)
779 },
780 marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","netparams":["1Address"],"id":1}`,
781 unmarshalled: &btcjson.SearchRawTransactionsCmd{
782 Address: "1Address",
783 Verbose: btcjson.Int(1),
784 Skip: btcjson.Int(0),
785 Count: btcjson.Int(100),
786 VinExtra: btcjson.Int(0),
787 Reverse: btcjson.Bool(false),
788 FilterAddrs: nil,
789 },
790 },
791 {
792 name: "searchrawtransactions",
793 newCmd: func() (interface{}, error) {
794 return btcjson.NewCmd("searchrawtransactions", "1Address", 0)
795 },
796 staticCmd: func() interface{} {
797 return btcjson.NewSearchRawTransactionsCmd(
798 "1Address",
799 btcjson.Int(0), nil, nil, nil, nil, nil,
800 )
801 },
802 marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","netparams":["1Address",0],"id":1}`,
803 unmarshalled: &btcjson.SearchRawTransactionsCmd{
804 Address: "1Address",
805 Verbose: btcjson.Int(0),
806 Skip: btcjson.Int(0),
807 Count: btcjson.Int(100),
808 VinExtra: btcjson.Int(0),
809 Reverse: btcjson.Bool(false),
810 FilterAddrs: nil,
811 },
812 },
813 {
814 name: "searchrawtransactions",
815 newCmd: func() (interface{}, error) {
816 return btcjson.NewCmd("searchrawtransactions", "1Address", 0, 5)
817 },
818 staticCmd: func() interface{} {
819 return btcjson.NewSearchRawTransactionsCmd(
820 "1Address",
821 btcjson.Int(0), btcjson.Int(5), nil, nil, nil, nil,
822 )
823 },
824 marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","netparams":["1Address",0,5],"id":1}`,
825 unmarshalled: &btcjson.SearchRawTransactionsCmd{
826 Address: "1Address",
827 Verbose: btcjson.Int(0),
828 Skip: btcjson.Int(5),
829 Count: btcjson.Int(100),
830 VinExtra: btcjson.Int(0),
831 Reverse: btcjson.Bool(false),
832 FilterAddrs: nil,
833 },
834 },
835 {
836 name: "searchrawtransactions",
837 newCmd: func() (interface{}, error) {
838 return btcjson.NewCmd("searchrawtransactions", "1Address", 0, 5, 10)
839 },
840 staticCmd: func() interface{} {
841 return btcjson.NewSearchRawTransactionsCmd(
842 "1Address",
843 btcjson.Int(0), btcjson.Int(5), btcjson.Int(10), nil, nil, nil,
844 )
845 },
846 marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","netparams":["1Address",0,5,10],"id":1}`,
847 unmarshalled: &btcjson.SearchRawTransactionsCmd{
848 Address: "1Address",
849 Verbose: btcjson.Int(0),
850 Skip: btcjson.Int(5),
851 Count: btcjson.Int(10),
852 VinExtra: btcjson.Int(0),
853 Reverse: btcjson.Bool(false),
854 FilterAddrs: nil,
855 },
856 },
857 {
858 name: "searchrawtransactions",
859 newCmd: func() (interface{}, error) {
860 return btcjson.NewCmd("searchrawtransactions", "1Address", 0, 5, 10, 1)
861 },
862 staticCmd: func() interface{} {
863 return btcjson.NewSearchRawTransactionsCmd(
864 "1Address",
865 btcjson.Int(0), btcjson.Int(5), btcjson.Int(10), btcjson.Int(1), nil, nil,
866 )
867 },
868 marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","netparams":["1Address",0,5,10,1],"id":1}`,
869 unmarshalled: &btcjson.SearchRawTransactionsCmd{
870 Address: "1Address",
871 Verbose: btcjson.Int(0),
872 Skip: btcjson.Int(5),
873 Count: btcjson.Int(10),
874 VinExtra: btcjson.Int(1),
875 Reverse: btcjson.Bool(false),
876 FilterAddrs: nil,
877 },
878 },
879 {
880 name: "searchrawtransactions",
881 newCmd: func() (interface{}, error) {
882 return btcjson.NewCmd("searchrawtransactions", "1Address", 0, 5, 10, 1, true)
883 },
884 staticCmd: func() interface{} {
885 return btcjson.NewSearchRawTransactionsCmd(
886 "1Address",
887 btcjson.Int(0), btcjson.Int(5), btcjson.Int(10), btcjson.Int(1), btcjson.Bool(true), nil,
888 )
889 },
890 marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","netparams":["1Address",0,5,10,1,true],"id":1}`,
891 unmarshalled: &btcjson.SearchRawTransactionsCmd{
892 Address: "1Address",
893 Verbose: btcjson.Int(0),
894 Skip: btcjson.Int(5),
895 Count: btcjson.Int(10),
896 VinExtra: btcjson.Int(1),
897 Reverse: btcjson.Bool(true),
898 FilterAddrs: nil,
899 },
900 },
901 {
902 name: "searchrawtransactions",
903 newCmd: func() (interface{}, error) {
904 return btcjson.NewCmd("searchrawtransactions", "1Address", 0, 5, 10, 1, true, []string{"1Address"})
905 },
906 staticCmd: func() interface{} {
907 return btcjson.NewSearchRawTransactionsCmd(
908 "1Address",
909 btcjson.Int(0),
910 btcjson.Int(5),
911 btcjson.Int(10),
912 btcjson.Int(1),
913 btcjson.Bool(true),
914 &[]string{"1Address"},
915 )
916 },
917 marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","netparams":["1Address",0,5,10,1,true,["1Address"]],"id":1}`,
918 unmarshalled: &btcjson.SearchRawTransactionsCmd{
919 Address: "1Address",
920 Verbose: btcjson.Int(0),
921 Skip: btcjson.Int(5),
922 Count: btcjson.Int(10),
923 VinExtra: btcjson.Int(1),
924 Reverse: btcjson.Bool(true),
925 FilterAddrs: &[]string{"1Address"},
926 },
927 },
928 {
929 name: "sendrawtransaction",
930 newCmd: func() (interface{}, error) {
931 return btcjson.NewCmd("sendrawtransaction", "1122")
932 },
933 staticCmd: func() interface{} {
934 return btcjson.NewSendRawTransactionCmd("1122", nil)
935 },
936 marshalled: `{"jsonrpc":"1.0","method":"sendrawtransaction","netparams":["1122"],"id":1}`,
937 unmarshalled: &btcjson.SendRawTransactionCmd{
938 HexTx: "1122",
939 AllowHighFees: btcjson.Bool(false),
940 },
941 },
942 {
943 name: "sendrawtransaction optional",
944 newCmd: func() (interface{}, error) {
945 return btcjson.NewCmd("sendrawtransaction", "1122", false)
946 },
947 staticCmd: func() interface{} {
948 return btcjson.NewSendRawTransactionCmd("1122", btcjson.Bool(false))
949 },
950 marshalled: `{"jsonrpc":"1.0","method":"sendrawtransaction","netparams":["1122",false],"id":1}`,
951 unmarshalled: &btcjson.SendRawTransactionCmd{
952 HexTx: "1122",
953 AllowHighFees: btcjson.Bool(false),
954 },
955 },
956 {
957 name: "setgenerate",
958 newCmd: func() (interface{}, error) {
959 return btcjson.NewCmd("setgenerate", true)
960 },
961 staticCmd: func() interface{} {
962 return btcjson.NewSetGenerateCmd(true, nil)
963 },
964 marshalled: `{"jsonrpc":"1.0","method":"setgenerate","netparams":[true],"id":1}`,
965 unmarshalled: &btcjson.SetGenerateCmd{
966 Generate: true,
967 GenProcLimit: btcjson.Int(-1),
968 },
969 },
970 {
971 name: "setgenerate optional",
972 newCmd: func() (interface{}, error) {
973 return btcjson.NewCmd("setgenerate", true, 6)
974 },
975 staticCmd: func() interface{} {
976 return btcjson.NewSetGenerateCmd(true, btcjson.Int(6))
977 },
978 marshalled: `{"jsonrpc":"1.0","method":"setgenerate","netparams":[true,6],"id":1}`,
979 unmarshalled: &btcjson.SetGenerateCmd{
980 Generate: true,
981 GenProcLimit: btcjson.Int(6),
982 },
983 },
984 {
985 name: "stop",
986 newCmd: func() (interface{}, error) {
987 return btcjson.NewCmd("stop")
988 },
989 staticCmd: func() interface{} {
990 return btcjson.NewStopCmd()
991 },
992 marshalled: `{"jsonrpc":"1.0","method":"stop","netparams":[],"id":1}`,
993 unmarshalled: &btcjson.StopCmd{},
994 },
995 {
996 name: "restart",
997 newCmd: func() (interface{}, error) {
998 return btcjson.NewCmd("restart")
999 },
1000 staticCmd: func() interface{} {
1001 return btcjson.NewRestartCmd()
1002 },
1003 marshalled: `{"jsonrpc":"1.0","method":"restart","netparams":[],"id":1}`,
1004 unmarshalled: &btcjson.RestartCmd{},
1005 },
1006 {
1007 name: "submitblock",
1008 newCmd: func() (interface{}, error) {
1009 return btcjson.NewCmd("submitblock", "112233")
1010 },
1011 staticCmd: func() interface{} {
1012 return btcjson.NewSubmitBlockCmd("112233", nil)
1013 },
1014 marshalled: `{"jsonrpc":"1.0","method":"submitblock","netparams":["112233"],"id":1}`,
1015 unmarshalled: &btcjson.SubmitBlockCmd{
1016 HexBlock: "112233",
1017 Options: nil,
1018 },
1019 },
1020 {
1021 name: "submitblock optional",
1022 newCmd: func() (interface{}, error) {
1023 return btcjson.NewCmd("submitblock", "112233", `{"workid":"12345"}`)
1024 },
1025 staticCmd: func() interface{} {
1026 options := btcjson.SubmitBlockOptions{
1027 WorkID: "12345",
1028 }
1029 return btcjson.NewSubmitBlockCmd("112233", &options)
1030 },
1031 marshalled: `{"jsonrpc":"1.0","method":"submitblock","netparams":["112233",{"workid":"12345"}],"id":1}`,
1032 unmarshalled: &btcjson.SubmitBlockCmd{
1033 HexBlock: "112233",
1034 Options: &btcjson.SubmitBlockOptions{
1035 WorkID: "12345",
1036 },
1037 },
1038 },
1039 {
1040 name: "uptime",
1041 newCmd: func() (interface{}, error) {
1042 return btcjson.NewCmd("uptime")
1043 },
1044 staticCmd: func() interface{} {
1045 return btcjson.NewUptimeCmd()
1046 },
1047 marshalled: `{"jsonrpc":"1.0","method":"uptime","netparams":[],"id":1}`,
1048 unmarshalled: &btcjson.UptimeCmd{},
1049 },
1050 {
1051 name: "validateaddress",
1052 newCmd: func() (interface{}, error) {
1053 return btcjson.NewCmd("validateaddress", "1Address")
1054 },
1055 staticCmd: func() interface{} {
1056 return btcjson.NewValidateAddressCmd("1Address")
1057 },
1058 marshalled: `{"jsonrpc":"1.0","method":"validateaddress","netparams":["1Address"],"id":1}`,
1059 unmarshalled: &btcjson.ValidateAddressCmd{
1060 Address: "1Address",
1061 },
1062 },
1063 {
1064 name: "verifychain",
1065 newCmd: func() (interface{}, error) {
1066 return btcjson.NewCmd("verifychain")
1067 },
1068 staticCmd: func() interface{} {
1069 return btcjson.NewVerifyChainCmd(nil, nil)
1070 },
1071 marshalled: `{"jsonrpc":"1.0","method":"verifychain","netparams":[],"id":1}`,
1072 unmarshalled: &btcjson.VerifyChainCmd{
1073 CheckLevel: btcjson.Int32(3),
1074 CheckDepth: btcjson.Int32(288),
1075 },
1076 },
1077 {
1078 name: "verifychain optional1",
1079 newCmd: func() (interface{}, error) {
1080 return btcjson.NewCmd("verifychain", 2)
1081 },
1082 staticCmd: func() interface{} {
1083 return btcjson.NewVerifyChainCmd(btcjson.Int32(2), nil)
1084 },
1085 marshalled: `{"jsonrpc":"1.0","method":"verifychain","netparams":[2],"id":1}`,
1086 unmarshalled: &btcjson.VerifyChainCmd{
1087 CheckLevel: btcjson.Int32(2),
1088 CheckDepth: btcjson.Int32(288),
1089 },
1090 },
1091 {
1092 name: "verifychain optional2",
1093 newCmd: func() (interface{}, error) {
1094 return btcjson.NewCmd("verifychain", 2, 500)
1095 },
1096 staticCmd: func() interface{} {
1097 return btcjson.NewVerifyChainCmd(btcjson.Int32(2), btcjson.Int32(500))
1098 },
1099 marshalled: `{"jsonrpc":"1.0","method":"verifychain","netparams":[2,500],"id":1}`,
1100 unmarshalled: &btcjson.VerifyChainCmd{
1101 CheckLevel: btcjson.Int32(2),
1102 CheckDepth: btcjson.Int32(500),
1103 },
1104 },
1105 {
1106 name: "verifymessage",
1107 newCmd: func() (interface{}, error) {
1108 return btcjson.NewCmd("verifymessage", "1Address", "301234", "test")
1109 },
1110 staticCmd: func() interface{} {
1111 return btcjson.NewVerifyMessageCmd("1Address", "301234", "test")
1112 },
1113 marshalled: `{"jsonrpc":"1.0","method":"verifymessage","netparams":["1Address","301234","test"],"id":1}`,
1114 unmarshalled: &btcjson.VerifyMessageCmd{
1115 Address: "1Address",
1116 Signature: "301234",
1117 Message: "test",
1118 },
1119 },
1120 {
1121 name: "verifytxoutproof",
1122 newCmd: func() (interface{}, error) {
1123 return btcjson.NewCmd("verifytxoutproof", "test")
1124 },
1125 staticCmd: func() interface{} {
1126 return btcjson.NewVerifyTxOutProofCmd("test")
1127 },
1128 marshalled: `{"jsonrpc":"1.0","method":"verifytxoutproof","netparams":["test"],"id":1}`,
1129 unmarshalled: &btcjson.VerifyTxOutProofCmd{
1130 Proof: "test",
1131 },
1132 },
1133 }
1134 t.Logf("Running %d tests", len(tests))
1135 for i, test := range tests {
1136 // Marshal the command as created by the new static command
1137 // creation function.
1138 marshalled, e := btcjson.MarshalCmd(testID, test.staticCmd())
1139 if e != nil {
1140 t.Errorf(
1141 "MarshalCmd #%d (%s) unexpected error: %v", i,
1142 test.name, e,
1143 )
1144 continue
1145 }
1146 if !bytes.Equal(marshalled, []byte(test.marshalled)) {
1147 t.Errorf(
1148 "Test #%d (%s) unexpected marshalled data - "+
1149 "got %s, want %s", i, test.name, marshalled,
1150 test.marshalled,
1151 )
1152 t.Errorf("\n%s\n%s", marshalled, test.marshalled)
1153 continue
1154 }
1155 // Ensure the command is created without error via the generic
1156 // new command creation function.
1157 cmd, e := test.newCmd()
1158 if e != nil {
1159 t.Errorf(
1160 "Test #%d (%s) unexpected NewCmd error: %v ",
1161 i, test.name, e,
1162 )
1163 }
1164 // Marshal the command as created by the generic new command
1165 // creation function.
1166 marshalled, e = btcjson.MarshalCmd(testID, cmd)
1167 if e != nil {
1168 t.Errorf(
1169 "MarshalCmd #%d (%s) unexpected error: %v", i,
1170 test.name, e,
1171 )
1172 continue
1173 }
1174 if !bytes.Equal(marshalled, []byte(test.marshalled)) {
1175 t.Errorf(
1176 "Test #%d (%s) unexpected marshalled data - "+
1177 "got %s, want %s", i, test.name, marshalled,
1178 test.marshalled,
1179 )
1180 continue
1181 }
1182 var request btcjson.Request
1183 if e = json.Unmarshal(marshalled, &request); E.Chk(e) {
1184 t.Errorf(
1185 "Test #%d (%s) unexpected error while "+
1186 "unmarshalling JSON-RPC request: %v", i,
1187 test.name, e,
1188 )
1189 continue
1190 }
1191 cmd, e = btcjson.UnmarshalCmd(&request)
1192 if e != nil {
1193 t.Errorf(
1194 "UnmarshalCmd #%d (%s) unexpected error: %v", i,
1195 test.name, e,
1196 )
1197 continue
1198 }
1199 if !reflect.DeepEqual(cmd, test.unmarshalled) {
1200 t.Errorf(
1201 "Test #%d (%s) unexpected unmarshalled command "+
1202 "- got %s, want %s", i, test.name,
1203 fmt.Sprintf("(%T) %+[1]v", cmd),
1204 fmt.Sprintf("(%T) %+[1]v\n", test.unmarshalled),
1205 )
1206 continue
1207 }
1208 }
1209 }
1210
1211 // TestChainSvrCmdErrors ensures any errors that occur in the command during custom mashal and unmarshal are as expected.
1212 func TestChainSvrCmdErrors(t *testing.T) {
1213 t.Parallel()
1214 tests := []struct {
1215 name string
1216 result interface{}
1217 marshalled string
1218 err error
1219 }{
1220 {
1221 name: "template request with invalid type",
1222 result: &btcjson.TemplateRequest{},
1223 marshalled: `{"mode":1}`,
1224 err: &json.UnmarshalTypeError{},
1225 },
1226 {
1227 name: "invalid template request sigoplimit field",
1228 result: &btcjson.TemplateRequest{},
1229 marshalled: `{"sigoplimit":"invalid"}`,
1230 err: btcjson.GeneralError{ErrorCode: btcjson.ErrInvalidType},
1231 },
1232 {
1233 name: "invalid template request sizelimit field",
1234 result: &btcjson.TemplateRequest{},
1235 marshalled: `{"sizelimit":"invalid"}`,
1236 err: btcjson.GeneralError{ErrorCode: btcjson.ErrInvalidType},
1237 },
1238 }
1239 t.Logf("Running %d tests", len(tests))
1240 for i, test := range tests {
1241 e := json.Unmarshal([]byte(test.marshalled), &test.result)
1242 if reflect.TypeOf(e) != reflect.TypeOf(test.err) {
1243 t.Errorf(
1244 "Test #%d (%s) wrong error - got %T (%v), "+
1245 "want %T", i, test.name, e, e, test.err,
1246 )
1247 continue
1248 }
1249 if terr, ok := test.err.(btcjson.GeneralError); ok {
1250 gotErrorCode := e.(btcjson.GeneralError).ErrorCode
1251 if gotErrorCode != terr.ErrorCode {
1252 t.Errorf(
1253 "Test #%d (%s) mismatched error code "+
1254 "- got %v (%v), want %v", i, test.name,
1255 gotErrorCode, terr, terr.ErrorCode,
1256 )
1257 continue
1258 }
1259 }
1260 }
1261 }
1262