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