github.com/lbryio/lbcd@v0.22.119/btcjson/chainsvrcmds_test.go (about) 1 // Copyright (c) 2014 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_test 6 7 import ( 8 "bytes" 9 "encoding/hex" 10 "encoding/json" 11 "fmt" 12 "reflect" 13 "testing" 14 15 "github.com/lbryio/lbcd/btcjson" 16 "github.com/lbryio/lbcd/wire" 17 ) 18 19 // TestChainSvrCmds tests all of the chain server commands marshal and unmarshal 20 // into valid results include handling of optional fields being omitted in the 21 // marshalled command, while optional fields with defaults have the default 22 // assigned on unmarshalled commands. 23 func TestChainSvrCmds(t *testing.T) { 24 t.Parallel() 25 26 testID := int(1) 27 tests := []struct { 28 name string 29 newCmd func() (interface{}, error) 30 staticCmd func() interface{} 31 marshalled string 32 unmarshalled interface{} 33 }{ 34 { 35 name: "addnode", 36 newCmd: func() (interface{}, error) { 37 return btcjson.NewCmd("addnode", "127.0.0.1", btcjson.ANRemove) 38 }, 39 staticCmd: func() interface{} { 40 return btcjson.NewAddNodeCmd("127.0.0.1", btcjson.ANRemove) 41 }, 42 marshalled: `{"jsonrpc":"1.0","method":"addnode","params":["127.0.0.1","remove"],"id":1}`, 43 unmarshalled: &btcjson.AddNodeCmd{Addr: "127.0.0.1", SubCmd: btcjson.ANRemove}, 44 }, 45 { 46 name: "createrawtransaction", 47 newCmd: func() (interface{}, error) { 48 return btcjson.NewCmd("createrawtransaction", `[{"txid":"123","vout":1}]`, 49 `{"456":0.0123}`) 50 }, 51 staticCmd: func() interface{} { 52 txInputs := []btcjson.TransactionInput{ 53 {Txid: "123", Vout: 1}, 54 } 55 txOutputs := map[string]interface{}{"456": .0123} 56 return btcjson.NewCreateRawTransactionCmd(txInputs, txOutputs, nil) 57 }, 58 marshalled: `{"jsonrpc":"1.0","method":"createrawtransaction","params":[[{"txid":"123","vout":1}],{"456":0.0123}],"id":1}`, 59 unmarshalled: &btcjson.CreateRawTransactionCmd{ 60 Inputs: []btcjson.TransactionInput{{Txid: "123", Vout: 1}}, 61 Outputs: map[string]interface{}{"456": .0123}, 62 }, 63 }, 64 { 65 name: "createrawtransaction - no inputs", 66 newCmd: func() (interface{}, error) { 67 return btcjson.NewCmd("createrawtransaction", `[]`, `{"456":0.0123}`) 68 }, 69 staticCmd: func() interface{} { 70 txOutputs := map[string]interface{}{"456": .0123} 71 return btcjson.NewCreateRawTransactionCmd(nil, txOutputs, nil) 72 }, 73 marshalled: `{"jsonrpc":"1.0","method":"createrawtransaction","params":[[],{"456":0.0123}],"id":1}`, 74 unmarshalled: &btcjson.CreateRawTransactionCmd{ 75 Inputs: []btcjson.TransactionInput{}, 76 Outputs: map[string]interface{}{"456": .0123}, 77 }, 78 }, 79 { 80 name: "createrawtransaction optional", 81 newCmd: func() (interface{}, error) { 82 return btcjson.NewCmd("createrawtransaction", `[{"txid":"123","vout":1}]`, 83 `{"456":0.0123}`, int64(12312333333)) 84 }, 85 staticCmd: func() interface{} { 86 txInputs := []btcjson.TransactionInput{ 87 {Txid: "123", Vout: 1}, 88 } 89 txOutputs := map[string]interface{}{"456": .0123} 90 return btcjson.NewCreateRawTransactionCmd(txInputs, txOutputs, btcjson.Int64(12312333333)) 91 }, 92 marshalled: `{"jsonrpc":"1.0","method":"createrawtransaction","params":[[{"txid":"123","vout":1}],{"456":0.0123},12312333333],"id":1}`, 93 unmarshalled: &btcjson.CreateRawTransactionCmd{ 94 Inputs: []btcjson.TransactionInput{{Txid: "123", Vout: 1}}, 95 Outputs: map[string]interface{}{"456": .0123}, 96 LockTime: btcjson.Int64(12312333333), 97 }, 98 }, 99 { 100 name: "createrawtransaction with data", 101 newCmd: func() (interface{}, error) { 102 return btcjson.NewCmd("createrawtransaction", `[{"txid":"123","vout":1}]`, 103 `{"data":"6a134920616d204672616374616c456e6372797074"}`) 104 }, 105 staticCmd: func() interface{} { 106 txInputs := []btcjson.TransactionInput{ 107 {Txid: "123", Vout: 1}, 108 } 109 txOutputs := map[string]interface{}{"data": "6a134920616d204672616374616c456e6372797074"} 110 return btcjson.NewCreateRawTransactionCmd(txInputs, txOutputs, nil) 111 }, 112 marshalled: `{"jsonrpc":"1.0","method":"createrawtransaction","params":[[{"txid":"123","vout":1}],{"data":"6a134920616d204672616374616c456e6372797074"}],"id":1}`, 113 unmarshalled: &btcjson.CreateRawTransactionCmd{ 114 Inputs: []btcjson.TransactionInput{{Txid: "123", Vout: 1}}, 115 Outputs: map[string]interface{}{"data": "6a134920616d204672616374616c456e6372797074"}, 116 }, 117 }, 118 { 119 name: "fundrawtransaction - empty opts", 120 newCmd: func() (i interface{}, e error) { 121 return btcjson.NewCmd("fundrawtransaction", "deadbeef", "{}") 122 }, 123 staticCmd: func() interface{} { 124 deadbeef, err := hex.DecodeString("deadbeef") 125 if err != nil { 126 panic(err) 127 } 128 return btcjson.NewFundRawTransactionCmd(deadbeef, btcjson.FundRawTransactionOpts{}, nil) 129 }, 130 marshalled: `{"jsonrpc":"1.0","method":"fundrawtransaction","params":["deadbeef",{}],"id":1}`, 131 unmarshalled: &btcjson.FundRawTransactionCmd{ 132 HexTx: "deadbeef", 133 Options: btcjson.FundRawTransactionOpts{}, 134 IsWitness: nil, 135 }, 136 }, 137 { 138 name: "fundrawtransaction - full opts", 139 newCmd: func() (i interface{}, e error) { 140 return btcjson.NewCmd("fundrawtransaction", "deadbeef", `{"changeAddress":"bcrt1qeeuctq9wutlcl5zatge7rjgx0k45228cxez655","changePosition":1,"change_type":"legacy","includeWatching":true,"lockUnspents":true,"feeRate":0.7,"subtractFeeFromOutputs":[0],"replaceable":true,"conf_target":8,"estimate_mode":"ECONOMICAL"}`) 141 }, 142 staticCmd: func() interface{} { 143 deadbeef, err := hex.DecodeString("deadbeef") 144 if err != nil { 145 panic(err) 146 } 147 changeAddress := "bcrt1qeeuctq9wutlcl5zatge7rjgx0k45228cxez655" 148 change := 1 149 changeType := btcjson.ChangeTypeLegacy 150 watching := true 151 lockUnspents := true 152 feeRate := 0.7 153 replaceable := true 154 confTarget := 8 155 156 return btcjson.NewFundRawTransactionCmd(deadbeef, btcjson.FundRawTransactionOpts{ 157 ChangeAddress: &changeAddress, 158 ChangePosition: &change, 159 ChangeType: &changeType, 160 IncludeWatching: &watching, 161 LockUnspents: &lockUnspents, 162 FeeRate: &feeRate, 163 SubtractFeeFromOutputs: []int{0}, 164 Replaceable: &replaceable, 165 ConfTarget: &confTarget, 166 EstimateMode: &btcjson.EstimateModeEconomical, 167 }, nil) 168 }, 169 marshalled: `{"jsonrpc":"1.0","method":"fundrawtransaction","params":["deadbeef",{"changeAddress":"bcrt1qeeuctq9wutlcl5zatge7rjgx0k45228cxez655","changePosition":1,"change_type":"legacy","includeWatching":true,"lockUnspents":true,"feeRate":0.7,"subtractFeeFromOutputs":[0],"replaceable":true,"conf_target":8,"estimate_mode":"ECONOMICAL"}],"id":1}`, 170 unmarshalled: func() interface{} { 171 changeAddress := "bcrt1qeeuctq9wutlcl5zatge7rjgx0k45228cxez655" 172 change := 1 173 changeType := btcjson.ChangeTypeLegacy 174 watching := true 175 lockUnspents := true 176 feeRate := 0.7 177 replaceable := true 178 confTarget := 8 179 return &btcjson.FundRawTransactionCmd{ 180 HexTx: "deadbeef", 181 Options: btcjson.FundRawTransactionOpts{ 182 ChangeAddress: &changeAddress, 183 ChangePosition: &change, 184 ChangeType: &changeType, 185 IncludeWatching: &watching, 186 LockUnspents: &lockUnspents, 187 FeeRate: &feeRate, 188 SubtractFeeFromOutputs: []int{0}, 189 Replaceable: &replaceable, 190 ConfTarget: &confTarget, 191 EstimateMode: &btcjson.EstimateModeEconomical, 192 }, 193 IsWitness: nil, 194 } 195 }(), 196 }, 197 { 198 name: "fundrawtransaction - iswitness", 199 newCmd: func() (i interface{}, e error) { 200 return btcjson.NewCmd("fundrawtransaction", "deadbeef", "{}", true) 201 }, 202 staticCmd: func() interface{} { 203 deadbeef, err := hex.DecodeString("deadbeef") 204 if err != nil { 205 panic(err) 206 } 207 t := true 208 return btcjson.NewFundRawTransactionCmd(deadbeef, btcjson.FundRawTransactionOpts{}, &t) 209 }, 210 marshalled: `{"jsonrpc":"1.0","method":"fundrawtransaction","params":["deadbeef",{},true],"id":1}`, 211 unmarshalled: &btcjson.FundRawTransactionCmd{ 212 HexTx: "deadbeef", 213 Options: btcjson.FundRawTransactionOpts{}, 214 IsWitness: func() *bool { 215 t := true 216 return &t 217 }(), 218 }, 219 }, 220 { 221 name: "decoderawtransaction", 222 newCmd: func() (interface{}, error) { 223 return btcjson.NewCmd("decoderawtransaction", "123") 224 }, 225 staticCmd: func() interface{} { 226 return btcjson.NewDecodeRawTransactionCmd("123") 227 }, 228 marshalled: `{"jsonrpc":"1.0","method":"decoderawtransaction","params":["123"],"id":1}`, 229 unmarshalled: &btcjson.DecodeRawTransactionCmd{HexTx: "123"}, 230 }, 231 { 232 name: "decodescript", 233 newCmd: func() (interface{}, error) { 234 return btcjson.NewCmd("decodescript", "00") 235 }, 236 staticCmd: func() interface{} { 237 return btcjson.NewDecodeScriptCmd("00") 238 }, 239 marshalled: `{"jsonrpc":"1.0","method":"decodescript","params":["00"],"id":1}`, 240 unmarshalled: &btcjson.DecodeScriptCmd{HexScript: "00"}, 241 }, 242 { 243 name: "deriveaddresses no range", 244 newCmd: func() (interface{}, error) { 245 return btcjson.NewCmd("deriveaddresses", "00") 246 }, 247 staticCmd: func() interface{} { 248 return btcjson.NewDeriveAddressesCmd("00", nil) 249 }, 250 marshalled: `{"jsonrpc":"1.0","method":"deriveaddresses","params":["00"],"id":1}`, 251 unmarshalled: &btcjson.DeriveAddressesCmd{Descriptor: "00"}, 252 }, 253 { 254 name: "deriveaddresses int range", 255 newCmd: func() (interface{}, error) { 256 return btcjson.NewCmd( 257 "deriveaddresses", "00", btcjson.DescriptorRange{Value: 2}) 258 }, 259 staticCmd: func() interface{} { 260 return btcjson.NewDeriveAddressesCmd( 261 "00", &btcjson.DescriptorRange{Value: 2}) 262 }, 263 marshalled: `{"jsonrpc":"1.0","method":"deriveaddresses","params":["00",2],"id":1}`, 264 unmarshalled: &btcjson.DeriveAddressesCmd{ 265 Descriptor: "00", 266 Range: &btcjson.DescriptorRange{Value: 2}, 267 }, 268 }, 269 { 270 name: "deriveaddresses slice range", 271 newCmd: func() (interface{}, error) { 272 return btcjson.NewCmd( 273 "deriveaddresses", "00", 274 btcjson.DescriptorRange{Value: []int{0, 2}}, 275 ) 276 }, 277 staticCmd: func() interface{} { 278 return btcjson.NewDeriveAddressesCmd( 279 "00", &btcjson.DescriptorRange{Value: []int{0, 2}}) 280 }, 281 marshalled: `{"jsonrpc":"1.0","method":"deriveaddresses","params":["00",[0,2]],"id":1}`, 282 unmarshalled: &btcjson.DeriveAddressesCmd{ 283 Descriptor: "00", 284 Range: &btcjson.DescriptorRange{Value: []int{0, 2}}, 285 }, 286 }, 287 { 288 name: "getaddednodeinfo", 289 newCmd: func() (interface{}, error) { 290 return btcjson.NewCmd("getaddednodeinfo", true) 291 }, 292 staticCmd: func() interface{} { 293 return btcjson.NewGetAddedNodeInfoCmd(true, nil) 294 }, 295 marshalled: `{"jsonrpc":"1.0","method":"getaddednodeinfo","params":[true],"id":1}`, 296 unmarshalled: &btcjson.GetAddedNodeInfoCmd{DNS: true, Node: nil}, 297 }, 298 { 299 name: "getaddednodeinfo optional", 300 newCmd: func() (interface{}, error) { 301 return btcjson.NewCmd("getaddednodeinfo", true, "127.0.0.1") 302 }, 303 staticCmd: func() interface{} { 304 return btcjson.NewGetAddedNodeInfoCmd(true, btcjson.String("127.0.0.1")) 305 }, 306 marshalled: `{"jsonrpc":"1.0","method":"getaddednodeinfo","params":[true,"127.0.0.1"],"id":1}`, 307 unmarshalled: &btcjson.GetAddedNodeInfoCmd{ 308 DNS: true, 309 Node: btcjson.String("127.0.0.1"), 310 }, 311 }, 312 { 313 name: "getbestblockhash", 314 newCmd: func() (interface{}, error) { 315 return btcjson.NewCmd("getbestblockhash") 316 }, 317 staticCmd: func() interface{} { 318 return btcjson.NewGetBestBlockHashCmd() 319 }, 320 marshalled: `{"jsonrpc":"1.0","method":"getbestblockhash","params":[],"id":1}`, 321 unmarshalled: &btcjson.GetBestBlockHashCmd{}, 322 }, 323 { 324 name: "getblock", 325 newCmd: func() (interface{}, error) { 326 return btcjson.NewCmd("getblock", "123", btcjson.Int(0)) 327 }, 328 staticCmd: func() interface{} { 329 return btcjson.NewGetBlockCmd("123", btcjson.Int(0)) 330 }, 331 marshalled: `{"jsonrpc":"1.0","method":"getblock","params":["123",0],"id":1}`, 332 unmarshalled: &btcjson.GetBlockCmd{ 333 Hash: "123", 334 Verbosity: btcjson.Int(0), 335 }, 336 }, 337 { 338 name: "getblock default verbosity", 339 newCmd: func() (interface{}, error) { 340 return btcjson.NewCmd("getblock", "123") 341 }, 342 staticCmd: func() interface{} { 343 return btcjson.NewGetBlockCmd("123", nil) 344 }, 345 marshalled: `{"jsonrpc":"1.0","method":"getblock","params":["123"],"id":1}`, 346 unmarshalled: &btcjson.GetBlockCmd{ 347 Hash: "123", 348 Verbosity: btcjson.Int(1), 349 }, 350 }, 351 { 352 name: "getblock required optional1", 353 newCmd: func() (interface{}, error) { 354 return btcjson.NewCmd("getblock", "123", btcjson.Int(1)) 355 }, 356 staticCmd: func() interface{} { 357 return btcjson.NewGetBlockCmd("123", btcjson.Int(1)) 358 }, 359 marshalled: `{"jsonrpc":"1.0","method":"getblock","params":["123",1],"id":1}`, 360 unmarshalled: &btcjson.GetBlockCmd{ 361 Hash: "123", 362 Verbosity: btcjson.Int(1), 363 }, 364 }, 365 { 366 name: "getblock required optional2", 367 newCmd: func() (interface{}, error) { 368 return btcjson.NewCmd("getblock", "123", btcjson.Int(2)) 369 }, 370 staticCmd: func() interface{} { 371 return btcjson.NewGetBlockCmd("123", btcjson.Int(2)) 372 }, 373 marshalled: `{"jsonrpc":"1.0","method":"getblock","params":["123",2],"id":1}`, 374 unmarshalled: &btcjson.GetBlockCmd{ 375 Hash: "123", 376 Verbosity: btcjson.Int(2), 377 }, 378 }, 379 { 380 name: "getblockchaininfo", 381 newCmd: func() (interface{}, error) { 382 return btcjson.NewCmd("getblockchaininfo") 383 }, 384 staticCmd: func() interface{} { 385 return btcjson.NewGetBlockChainInfoCmd() 386 }, 387 marshalled: `{"jsonrpc":"1.0","method":"getblockchaininfo","params":[],"id":1}`, 388 unmarshalled: &btcjson.GetBlockChainInfoCmd{}, 389 }, 390 { 391 name: "getblockcount", 392 newCmd: func() (interface{}, error) { 393 return btcjson.NewCmd("getblockcount") 394 }, 395 staticCmd: func() interface{} { 396 return btcjson.NewGetBlockCountCmd() 397 }, 398 marshalled: `{"jsonrpc":"1.0","method":"getblockcount","params":[],"id":1}`, 399 unmarshalled: &btcjson.GetBlockCountCmd{}, 400 }, 401 { 402 name: "getblockfilter", 403 newCmd: func() (interface{}, error) { 404 return btcjson.NewCmd("getblockfilter", "0000afaf") 405 }, 406 staticCmd: func() interface{} { 407 return btcjson.NewGetBlockFilterCmd("0000afaf", nil) 408 }, 409 marshalled: `{"jsonrpc":"1.0","method":"getblockfilter","params":["0000afaf"],"id":1}`, 410 unmarshalled: &btcjson.GetBlockFilterCmd{BlockHash: "0000afaf", FilterType: nil}, 411 }, 412 { 413 name: "getblockfilter optional filtertype", 414 newCmd: func() (interface{}, error) { 415 return btcjson.NewCmd("getblockfilter", "0000afaf", "basic") 416 }, 417 staticCmd: func() interface{} { 418 return btcjson.NewGetBlockFilterCmd("0000afaf", btcjson.NewFilterTypeName(btcjson.FilterTypeBasic)) 419 }, 420 marshalled: `{"jsonrpc":"1.0","method":"getblockfilter","params":["0000afaf","basic"],"id":1}`, 421 unmarshalled: &btcjson.GetBlockFilterCmd{BlockHash: "0000afaf", FilterType: btcjson.NewFilterTypeName(btcjson.FilterTypeBasic)}, 422 }, 423 { 424 name: "getblockhash", 425 newCmd: func() (interface{}, error) { 426 return btcjson.NewCmd("getblockhash", 123) 427 }, 428 staticCmd: func() interface{} { 429 return btcjson.NewGetBlockHashCmd(123) 430 }, 431 marshalled: `{"jsonrpc":"1.0","method":"getblockhash","params":[123],"id":1}`, 432 unmarshalled: &btcjson.GetBlockHashCmd{Index: 123}, 433 }, 434 { 435 name: "getblockheader", 436 newCmd: func() (interface{}, error) { 437 return btcjson.NewCmd("getblockheader", "123") 438 }, 439 staticCmd: func() interface{} { 440 return btcjson.NewGetBlockHeaderCmd("123", nil) 441 }, 442 marshalled: `{"jsonrpc":"1.0","method":"getblockheader","params":["123"],"id":1}`, 443 unmarshalled: &btcjson.GetBlockHeaderCmd{ 444 Hash: "123", 445 Verbose: btcjson.Bool(true), 446 }, 447 }, 448 { 449 name: "getblockstats height", 450 newCmd: func() (interface{}, error) { 451 return btcjson.NewCmd("getblockstats", btcjson.HashOrHeight{Value: 123}) 452 }, 453 staticCmd: func() interface{} { 454 return btcjson.NewGetBlockStatsCmd(btcjson.HashOrHeight{Value: 123}, nil) 455 }, 456 marshalled: `{"jsonrpc":"1.0","method":"getblockstats","params":[123],"id":1}`, 457 unmarshalled: &btcjson.GetBlockStatsCmd{ 458 HashOrHeight: btcjson.HashOrHeight{Value: 123}, 459 }, 460 }, 461 { 462 name: "getblockstats hash", 463 newCmd: func() (interface{}, error) { 464 return btcjson.NewCmd("getblockstats", btcjson.HashOrHeight{Value: "deadbeef"}) 465 }, 466 staticCmd: func() interface{} { 467 return btcjson.NewGetBlockStatsCmd(btcjson.HashOrHeight{Value: "deadbeef"}, nil) 468 }, 469 marshalled: `{"jsonrpc":"1.0","method":"getblockstats","params":["deadbeef"],"id":1}`, 470 unmarshalled: &btcjson.GetBlockStatsCmd{ 471 HashOrHeight: btcjson.HashOrHeight{Value: "deadbeef"}, 472 }, 473 }, 474 { 475 name: "getblockstats height optional stats", 476 newCmd: func() (interface{}, error) { 477 return btcjson.NewCmd("getblockstats", btcjson.HashOrHeight{Value: 123}, []string{"avgfee", "maxfee"}) 478 }, 479 staticCmd: func() interface{} { 480 return btcjson.NewGetBlockStatsCmd(btcjson.HashOrHeight{Value: 123}, &[]string{"avgfee", "maxfee"}) 481 }, 482 marshalled: `{"jsonrpc":"1.0","method":"getblockstats","params":[123,["avgfee","maxfee"]],"id":1}`, 483 unmarshalled: &btcjson.GetBlockStatsCmd{ 484 HashOrHeight: btcjson.HashOrHeight{Value: 123}, 485 Stats: &[]string{"avgfee", "maxfee"}, 486 }, 487 }, 488 { 489 name: "getblockstats hash optional stats", 490 newCmd: func() (interface{}, error) { 491 return btcjson.NewCmd("getblockstats", btcjson.HashOrHeight{Value: "deadbeef"}, []string{"avgfee", "maxfee"}) 492 }, 493 staticCmd: func() interface{} { 494 return btcjson.NewGetBlockStatsCmd(btcjson.HashOrHeight{Value: "deadbeef"}, &[]string{"avgfee", "maxfee"}) 495 }, 496 marshalled: `{"jsonrpc":"1.0","method":"getblockstats","params":["deadbeef",["avgfee","maxfee"]],"id":1}`, 497 unmarshalled: &btcjson.GetBlockStatsCmd{ 498 HashOrHeight: btcjson.HashOrHeight{Value: "deadbeef"}, 499 Stats: &[]string{"avgfee", "maxfee"}, 500 }, 501 }, 502 { 503 name: "getblocktemplate", 504 newCmd: func() (interface{}, error) { 505 return btcjson.NewCmd("getblocktemplate") 506 }, 507 staticCmd: func() interface{} { 508 return btcjson.NewGetBlockTemplateCmd(nil) 509 }, 510 marshalled: `{"jsonrpc":"1.0","method":"getblocktemplate","params":[],"id":1}`, 511 unmarshalled: &btcjson.GetBlockTemplateCmd{Request: nil}, 512 }, 513 { 514 name: "getblocktemplate optional - template request", 515 newCmd: func() (interface{}, error) { 516 return btcjson.NewCmd("getblocktemplate", `{"mode":"template","capabilities":["longpoll","coinbasetxn"]}`) 517 }, 518 staticCmd: func() interface{} { 519 template := btcjson.TemplateRequest{ 520 Mode: "template", 521 Capabilities: []string{"longpoll", "coinbasetxn"}, 522 } 523 return btcjson.NewGetBlockTemplateCmd(&template) 524 }, 525 marshalled: `{"jsonrpc":"1.0","method":"getblocktemplate","params":[{"mode":"template","capabilities":["longpoll","coinbasetxn"]}],"id":1}`, 526 unmarshalled: &btcjson.GetBlockTemplateCmd{ 527 Request: &btcjson.TemplateRequest{ 528 Mode: "template", 529 Capabilities: []string{"longpoll", "coinbasetxn"}, 530 }, 531 }, 532 }, 533 { 534 name: "getblocktemplate optional - template request with tweaks", 535 newCmd: func() (interface{}, error) { 536 return btcjson.NewCmd("getblocktemplate", `{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":500,"sizelimit":100000000,"maxversion":2}`) 537 }, 538 staticCmd: func() interface{} { 539 template := btcjson.TemplateRequest{ 540 Mode: "template", 541 Capabilities: []string{"longpoll", "coinbasetxn"}, 542 SigOpLimit: 500, 543 SizeLimit: 100000000, 544 MaxVersion: 2, 545 } 546 return btcjson.NewGetBlockTemplateCmd(&template) 547 }, 548 marshalled: `{"jsonrpc":"1.0","method":"getblocktemplate","params":[{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":500,"sizelimit":100000000,"maxversion":2}],"id":1}`, 549 unmarshalled: &btcjson.GetBlockTemplateCmd{ 550 Request: &btcjson.TemplateRequest{ 551 Mode: "template", 552 Capabilities: []string{"longpoll", "coinbasetxn"}, 553 SigOpLimit: int64(500), 554 SizeLimit: int64(100000000), 555 MaxVersion: 2, 556 }, 557 }, 558 }, 559 { 560 name: "getblocktemplate optional - template request with tweaks 2", 561 newCmd: func() (interface{}, error) { 562 return btcjson.NewCmd("getblocktemplate", `{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":true,"sizelimit":100000000,"maxversion":2}`) 563 }, 564 staticCmd: func() interface{} { 565 template := btcjson.TemplateRequest{ 566 Mode: "template", 567 Capabilities: []string{"longpoll", "coinbasetxn"}, 568 SigOpLimit: true, 569 SizeLimit: 100000000, 570 MaxVersion: 2, 571 } 572 return btcjson.NewGetBlockTemplateCmd(&template) 573 }, 574 marshalled: `{"jsonrpc":"1.0","method":"getblocktemplate","params":[{"mode":"template","capabilities":["longpoll","coinbasetxn"],"sigoplimit":true,"sizelimit":100000000,"maxversion":2}],"id":1}`, 575 unmarshalled: &btcjson.GetBlockTemplateCmd{ 576 Request: &btcjson.TemplateRequest{ 577 Mode: "template", 578 Capabilities: []string{"longpoll", "coinbasetxn"}, 579 SigOpLimit: true, 580 SizeLimit: int64(100000000), 581 MaxVersion: 2, 582 }, 583 }, 584 }, 585 { 586 name: "getcfilter", 587 newCmd: func() (interface{}, error) { 588 return btcjson.NewCmd("getcfilter", "123", 589 wire.GCSFilterRegular) 590 }, 591 staticCmd: func() interface{} { 592 return btcjson.NewGetCFilterCmd("123", 593 wire.GCSFilterRegular) 594 }, 595 marshalled: `{"jsonrpc":"1.0","method":"getcfilter","params":["123",0],"id":1}`, 596 unmarshalled: &btcjson.GetCFilterCmd{ 597 Hash: "123", 598 FilterType: wire.GCSFilterRegular, 599 }, 600 }, 601 { 602 name: "getcfilterheader", 603 newCmd: func() (interface{}, error) { 604 return btcjson.NewCmd("getcfilterheader", "123", 605 wire.GCSFilterRegular) 606 }, 607 staticCmd: func() interface{} { 608 return btcjson.NewGetCFilterHeaderCmd("123", 609 wire.GCSFilterRegular) 610 }, 611 marshalled: `{"jsonrpc":"1.0","method":"getcfilterheader","params":["123",0],"id":1}`, 612 unmarshalled: &btcjson.GetCFilterHeaderCmd{ 613 Hash: "123", 614 FilterType: wire.GCSFilterRegular, 615 }, 616 }, 617 { 618 name: "getchaintips", 619 newCmd: func() (interface{}, error) { 620 return btcjson.NewCmd("getchaintips") 621 }, 622 staticCmd: func() interface{} { 623 return btcjson.NewGetChainTipsCmd() 624 }, 625 marshalled: `{"jsonrpc":"1.0","method":"getchaintips","params":[],"id":1}`, 626 unmarshalled: &btcjson.GetChainTipsCmd{}, 627 }, 628 { 629 name: "getchaintxstats", 630 newCmd: func() (interface{}, error) { 631 return btcjson.NewCmd("getchaintxstats") 632 }, 633 staticCmd: func() interface{} { 634 return btcjson.NewGetChainTxStatsCmd(nil, nil) 635 }, 636 marshalled: `{"jsonrpc":"1.0","method":"getchaintxstats","params":[],"id":1}`, 637 unmarshalled: &btcjson.GetChainTxStatsCmd{}, 638 }, 639 { 640 name: "getchaintxstats optional nblocks", 641 newCmd: func() (interface{}, error) { 642 return btcjson.NewCmd("getchaintxstats", btcjson.Int32(1000)) 643 }, 644 staticCmd: func() interface{} { 645 return btcjson.NewGetChainTxStatsCmd(btcjson.Int32(1000), nil) 646 }, 647 marshalled: `{"jsonrpc":"1.0","method":"getchaintxstats","params":[1000],"id":1}`, 648 unmarshalled: &btcjson.GetChainTxStatsCmd{ 649 NBlocks: btcjson.Int32(1000), 650 }, 651 }, 652 { 653 name: "getchaintxstats optional nblocks and blockhash", 654 newCmd: func() (interface{}, error) { 655 return btcjson.NewCmd("getchaintxstats", btcjson.Int32(1000), btcjson.String("0000afaf")) 656 }, 657 staticCmd: func() interface{} { 658 return btcjson.NewGetChainTxStatsCmd(btcjson.Int32(1000), btcjson.String("0000afaf")) 659 }, 660 marshalled: `{"jsonrpc":"1.0","method":"getchaintxstats","params":[1000,"0000afaf"],"id":1}`, 661 unmarshalled: &btcjson.GetChainTxStatsCmd{ 662 NBlocks: btcjson.Int32(1000), 663 BlockHash: btcjson.String("0000afaf"), 664 }, 665 }, 666 { 667 name: "getconnectioncount", 668 newCmd: func() (interface{}, error) { 669 return btcjson.NewCmd("getconnectioncount") 670 }, 671 staticCmd: func() interface{} { 672 return btcjson.NewGetConnectionCountCmd() 673 }, 674 marshalled: `{"jsonrpc":"1.0","method":"getconnectioncount","params":[],"id":1}`, 675 unmarshalled: &btcjson.GetConnectionCountCmd{}, 676 }, 677 { 678 name: "getdifficulty", 679 newCmd: func() (interface{}, error) { 680 return btcjson.NewCmd("getdifficulty") 681 }, 682 staticCmd: func() interface{} { 683 return btcjson.NewGetDifficultyCmd() 684 }, 685 marshalled: `{"jsonrpc":"1.0","method":"getdifficulty","params":[],"id":1}`, 686 unmarshalled: &btcjson.GetDifficultyCmd{}, 687 }, 688 { 689 name: "getgenerate", 690 newCmd: func() (interface{}, error) { 691 return btcjson.NewCmd("getgenerate") 692 }, 693 staticCmd: func() interface{} { 694 return btcjson.NewGetGenerateCmd() 695 }, 696 marshalled: `{"jsonrpc":"1.0","method":"getgenerate","params":[],"id":1}`, 697 unmarshalled: &btcjson.GetGenerateCmd{}, 698 }, 699 { 700 name: "gethashespersec", 701 newCmd: func() (interface{}, error) { 702 return btcjson.NewCmd("gethashespersec") 703 }, 704 staticCmd: func() interface{} { 705 return btcjson.NewGetHashesPerSecCmd() 706 }, 707 marshalled: `{"jsonrpc":"1.0","method":"gethashespersec","params":[],"id":1}`, 708 unmarshalled: &btcjson.GetHashesPerSecCmd{}, 709 }, 710 { 711 name: "getinfo", 712 newCmd: func() (interface{}, error) { 713 return btcjson.NewCmd("getinfo") 714 }, 715 staticCmd: func() interface{} { 716 return btcjson.NewGetInfoCmd() 717 }, 718 marshalled: `{"jsonrpc":"1.0","method":"getinfo","params":[],"id":1}`, 719 unmarshalled: &btcjson.GetInfoCmd{}, 720 }, 721 { 722 name: "getmempoolentry", 723 newCmd: func() (interface{}, error) { 724 return btcjson.NewCmd("getmempoolentry", "txhash") 725 }, 726 staticCmd: func() interface{} { 727 return btcjson.NewGetMempoolEntryCmd("txhash") 728 }, 729 marshalled: `{"jsonrpc":"1.0","method":"getmempoolentry","params":["txhash"],"id":1}`, 730 unmarshalled: &btcjson.GetMempoolEntryCmd{ 731 TxID: "txhash", 732 }, 733 }, 734 { 735 name: "getmempoolinfo", 736 newCmd: func() (interface{}, error) { 737 return btcjson.NewCmd("getmempoolinfo") 738 }, 739 staticCmd: func() interface{} { 740 return btcjson.NewGetMempoolInfoCmd() 741 }, 742 marshalled: `{"jsonrpc":"1.0","method":"getmempoolinfo","params":[],"id":1}`, 743 unmarshalled: &btcjson.GetMempoolInfoCmd{}, 744 }, 745 { 746 name: "getmininginfo", 747 newCmd: func() (interface{}, error) { 748 return btcjson.NewCmd("getmininginfo") 749 }, 750 staticCmd: func() interface{} { 751 return btcjson.NewGetMiningInfoCmd() 752 }, 753 marshalled: `{"jsonrpc":"1.0","method":"getmininginfo","params":[],"id":1}`, 754 unmarshalled: &btcjson.GetMiningInfoCmd{}, 755 }, 756 { 757 name: "getnetworkinfo", 758 newCmd: func() (interface{}, error) { 759 return btcjson.NewCmd("getnetworkinfo") 760 }, 761 staticCmd: func() interface{} { 762 return btcjson.NewGetNetworkInfoCmd() 763 }, 764 marshalled: `{"jsonrpc":"1.0","method":"getnetworkinfo","params":[],"id":1}`, 765 unmarshalled: &btcjson.GetNetworkInfoCmd{}, 766 }, 767 { 768 name: "getnettotals", 769 newCmd: func() (interface{}, error) { 770 return btcjson.NewCmd("getnettotals") 771 }, 772 staticCmd: func() interface{} { 773 return btcjson.NewGetNetTotalsCmd() 774 }, 775 marshalled: `{"jsonrpc":"1.0","method":"getnettotals","params":[],"id":1}`, 776 unmarshalled: &btcjson.GetNetTotalsCmd{}, 777 }, 778 { 779 name: "getnetworkhashps", 780 newCmd: func() (interface{}, error) { 781 return btcjson.NewCmd("getnetworkhashps") 782 }, 783 staticCmd: func() interface{} { 784 return btcjson.NewGetNetworkHashPSCmd(nil, nil) 785 }, 786 marshalled: `{"jsonrpc":"1.0","method":"getnetworkhashps","params":[],"id":1}`, 787 unmarshalled: &btcjson.GetNetworkHashPSCmd{ 788 Blocks: btcjson.Int(120), 789 Height: btcjson.Int(-1), 790 }, 791 }, 792 { 793 name: "getnetworkhashps optional1", 794 newCmd: func() (interface{}, error) { 795 return btcjson.NewCmd("getnetworkhashps", 200) 796 }, 797 staticCmd: func() interface{} { 798 return btcjson.NewGetNetworkHashPSCmd(btcjson.Int(200), nil) 799 }, 800 marshalled: `{"jsonrpc":"1.0","method":"getnetworkhashps","params":[200],"id":1}`, 801 unmarshalled: &btcjson.GetNetworkHashPSCmd{ 802 Blocks: btcjson.Int(200), 803 Height: btcjson.Int(-1), 804 }, 805 }, 806 { 807 name: "getnetworkhashps optional2", 808 newCmd: func() (interface{}, error) { 809 return btcjson.NewCmd("getnetworkhashps", 200, 123) 810 }, 811 staticCmd: func() interface{} { 812 return btcjson.NewGetNetworkHashPSCmd(btcjson.Int(200), btcjson.Int(123)) 813 }, 814 marshalled: `{"jsonrpc":"1.0","method":"getnetworkhashps","params":[200,123],"id":1}`, 815 unmarshalled: &btcjson.GetNetworkHashPSCmd{ 816 Blocks: btcjson.Int(200), 817 Height: btcjson.Int(123), 818 }, 819 }, 820 { 821 name: "getnodeaddresses", 822 newCmd: func() (interface{}, error) { 823 return btcjson.NewCmd("getnodeaddresses") 824 }, 825 staticCmd: func() interface{} { 826 return btcjson.NewGetNodeAddressesCmd(nil) 827 }, 828 marshalled: `{"jsonrpc":"1.0","method":"getnodeaddresses","params":[],"id":1}`, 829 unmarshalled: &btcjson.GetNodeAddressesCmd{ 830 Count: btcjson.Int32(1), 831 }, 832 }, 833 { 834 name: "getnodeaddresses optional", 835 newCmd: func() (interface{}, error) { 836 return btcjson.NewCmd("getnodeaddresses", 10) 837 }, 838 staticCmd: func() interface{} { 839 return btcjson.NewGetNodeAddressesCmd(btcjson.Int32(10)) 840 }, 841 marshalled: `{"jsonrpc":"1.0","method":"getnodeaddresses","params":[10],"id":1}`, 842 unmarshalled: &btcjson.GetNodeAddressesCmd{ 843 Count: btcjson.Int32(10), 844 }, 845 }, 846 { 847 name: "getpeerinfo", 848 newCmd: func() (interface{}, error) { 849 return btcjson.NewCmd("getpeerinfo") 850 }, 851 staticCmd: func() interface{} { 852 return btcjson.NewGetPeerInfoCmd() 853 }, 854 marshalled: `{"jsonrpc":"1.0","method":"getpeerinfo","params":[],"id":1}`, 855 unmarshalled: &btcjson.GetPeerInfoCmd{}, 856 }, 857 { 858 name: "getrawmempool", 859 newCmd: func() (interface{}, error) { 860 return btcjson.NewCmd("getrawmempool") 861 }, 862 staticCmd: func() interface{} { 863 return btcjson.NewGetRawMempoolCmd(nil) 864 }, 865 marshalled: `{"jsonrpc":"1.0","method":"getrawmempool","params":[],"id":1}`, 866 unmarshalled: &btcjson.GetRawMempoolCmd{ 867 Verbose: btcjson.Bool(false), 868 }, 869 }, 870 { 871 name: "getrawmempool optional", 872 newCmd: func() (interface{}, error) { 873 return btcjson.NewCmd("getrawmempool", false) 874 }, 875 staticCmd: func() interface{} { 876 return btcjson.NewGetRawMempoolCmd(btcjson.Bool(false)) 877 }, 878 marshalled: `{"jsonrpc":"1.0","method":"getrawmempool","params":[false],"id":1}`, 879 unmarshalled: &btcjson.GetRawMempoolCmd{ 880 Verbose: btcjson.Bool(false), 881 }, 882 }, 883 { 884 name: "getrawtransaction", 885 newCmd: func() (interface{}, error) { 886 return btcjson.NewCmd("getrawtransaction", "123") 887 }, 888 staticCmd: func() interface{} { 889 return btcjson.NewGetRawTransactionCmd("123", nil) 890 }, 891 marshalled: `{"jsonrpc":"1.0","method":"getrawtransaction","params":["123"],"id":1}`, 892 unmarshalled: &btcjson.GetRawTransactionCmd{ 893 Txid: "123", 894 Verbose: btcjson.Bool(false), 895 }, 896 }, 897 { 898 name: "getrawtransaction optional", 899 newCmd: func() (interface{}, error) { 900 return btcjson.NewCmd("getrawtransaction", "123", true) 901 }, 902 staticCmd: func() interface{} { 903 return btcjson.NewGetRawTransactionCmd("123", btcjson.Bool(true)) 904 }, 905 marshalled: `{"jsonrpc":"1.0","method":"getrawtransaction","params":["123",true],"id":1}`, 906 unmarshalled: &btcjson.GetRawTransactionCmd{ 907 Txid: "123", 908 Verbose: btcjson.Bool(true), 909 }, 910 }, 911 { 912 name: "gettxout", 913 newCmd: func() (interface{}, error) { 914 return btcjson.NewCmd("gettxout", "123", 1) 915 }, 916 staticCmd: func() interface{} { 917 return btcjson.NewGetTxOutCmd("123", 1, nil) 918 }, 919 marshalled: `{"jsonrpc":"1.0","method":"gettxout","params":["123",1],"id":1}`, 920 unmarshalled: &btcjson.GetTxOutCmd{ 921 Txid: "123", 922 Vout: 1, 923 IncludeMempool: btcjson.Bool(true), 924 }, 925 }, 926 { 927 name: "gettxout optional", 928 newCmd: func() (interface{}, error) { 929 return btcjson.NewCmd("gettxout", "123", 1, true) 930 }, 931 staticCmd: func() interface{} { 932 return btcjson.NewGetTxOutCmd("123", 1, btcjson.Bool(true)) 933 }, 934 marshalled: `{"jsonrpc":"1.0","method":"gettxout","params":["123",1,true],"id":1}`, 935 unmarshalled: &btcjson.GetTxOutCmd{ 936 Txid: "123", 937 Vout: 1, 938 IncludeMempool: btcjson.Bool(true), 939 }, 940 }, 941 { 942 name: "gettxoutproof", 943 newCmd: func() (interface{}, error) { 944 return btcjson.NewCmd("gettxoutproof", []string{"123", "456"}) 945 }, 946 staticCmd: func() interface{} { 947 return btcjson.NewGetTxOutProofCmd([]string{"123", "456"}, nil) 948 }, 949 marshalled: `{"jsonrpc":"1.0","method":"gettxoutproof","params":[["123","456"]],"id":1}`, 950 unmarshalled: &btcjson.GetTxOutProofCmd{ 951 TxIDs: []string{"123", "456"}, 952 }, 953 }, 954 { 955 name: "gettxoutproof optional", 956 newCmd: func() (interface{}, error) { 957 return btcjson.NewCmd("gettxoutproof", []string{"123", "456"}, 958 btcjson.String("000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf")) 959 }, 960 staticCmd: func() interface{} { 961 return btcjson.NewGetTxOutProofCmd([]string{"123", "456"}, 962 btcjson.String("000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf")) 963 }, 964 marshalled: `{"jsonrpc":"1.0","method":"gettxoutproof","params":[["123","456"],` + 965 `"000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf"],"id":1}`, 966 unmarshalled: &btcjson.GetTxOutProofCmd{ 967 TxIDs: []string{"123", "456"}, 968 BlockHash: btcjson.String("000000000000034a7dedef4a161fa058a2d67a173a90155f3a2fe6fc132e0ebf"), 969 }, 970 }, 971 { 972 name: "gettxoutsetinfo", 973 newCmd: func() (interface{}, error) { 974 return btcjson.NewCmd("gettxoutsetinfo") 975 }, 976 staticCmd: func() interface{} { 977 return btcjson.NewGetTxOutSetInfoCmd() 978 }, 979 marshalled: `{"jsonrpc":"1.0","method":"gettxoutsetinfo","params":[],"id":1}`, 980 unmarshalled: &btcjson.GetTxOutSetInfoCmd{}, 981 }, 982 { 983 name: "getwork", 984 newCmd: func() (interface{}, error) { 985 return btcjson.NewCmd("getwork") 986 }, 987 staticCmd: func() interface{} { 988 return btcjson.NewGetWorkCmd(nil) 989 }, 990 marshalled: `{"jsonrpc":"1.0","method":"getwork","params":[],"id":1}`, 991 unmarshalled: &btcjson.GetWorkCmd{ 992 Data: nil, 993 }, 994 }, 995 { 996 name: "getwork optional", 997 newCmd: func() (interface{}, error) { 998 return btcjson.NewCmd("getwork", "00112233") 999 }, 1000 staticCmd: func() interface{} { 1001 return btcjson.NewGetWorkCmd(btcjson.String("00112233")) 1002 }, 1003 marshalled: `{"jsonrpc":"1.0","method":"getwork","params":["00112233"],"id":1}`, 1004 unmarshalled: &btcjson.GetWorkCmd{ 1005 Data: btcjson.String("00112233"), 1006 }, 1007 }, 1008 { 1009 name: "help", 1010 newCmd: func() (interface{}, error) { 1011 return btcjson.NewCmd("help") 1012 }, 1013 staticCmd: func() interface{} { 1014 return btcjson.NewHelpCmd(nil) 1015 }, 1016 marshalled: `{"jsonrpc":"1.0","method":"help","params":[],"id":1}`, 1017 unmarshalled: &btcjson.HelpCmd{ 1018 Command: nil, 1019 }, 1020 }, 1021 { 1022 name: "help optional", 1023 newCmd: func() (interface{}, error) { 1024 return btcjson.NewCmd("help", "getblock") 1025 }, 1026 staticCmd: func() interface{} { 1027 return btcjson.NewHelpCmd(btcjson.String("getblock")) 1028 }, 1029 marshalled: `{"jsonrpc":"1.0","method":"help","params":["getblock"],"id":1}`, 1030 unmarshalled: &btcjson.HelpCmd{ 1031 Command: btcjson.String("getblock"), 1032 }, 1033 }, 1034 { 1035 name: "invalidateblock", 1036 newCmd: func() (interface{}, error) { 1037 return btcjson.NewCmd("invalidateblock", "123") 1038 }, 1039 staticCmd: func() interface{} { 1040 return btcjson.NewInvalidateBlockCmd("123") 1041 }, 1042 marshalled: `{"jsonrpc":"1.0","method":"invalidateblock","params":["123"],"id":1}`, 1043 unmarshalled: &btcjson.InvalidateBlockCmd{ 1044 BlockHash: "123", 1045 }, 1046 }, 1047 { 1048 name: "ping", 1049 newCmd: func() (interface{}, error) { 1050 return btcjson.NewCmd("ping") 1051 }, 1052 staticCmd: func() interface{} { 1053 return btcjson.NewPingCmd() 1054 }, 1055 marshalled: `{"jsonrpc":"1.0","method":"ping","params":[],"id":1}`, 1056 unmarshalled: &btcjson.PingCmd{}, 1057 }, 1058 { 1059 name: "preciousblock", 1060 newCmd: func() (interface{}, error) { 1061 return btcjson.NewCmd("preciousblock", "0123") 1062 }, 1063 staticCmd: func() interface{} { 1064 return btcjson.NewPreciousBlockCmd("0123") 1065 }, 1066 marshalled: `{"jsonrpc":"1.0","method":"preciousblock","params":["0123"],"id":1}`, 1067 unmarshalled: &btcjson.PreciousBlockCmd{ 1068 BlockHash: "0123", 1069 }, 1070 }, 1071 { 1072 name: "reconsiderblock", 1073 newCmd: func() (interface{}, error) { 1074 return btcjson.NewCmd("reconsiderblock", "123") 1075 }, 1076 staticCmd: func() interface{} { 1077 return btcjson.NewReconsiderBlockCmd("123") 1078 }, 1079 marshalled: `{"jsonrpc":"1.0","method":"reconsiderblock","params":["123"],"id":1}`, 1080 unmarshalled: &btcjson.ReconsiderBlockCmd{ 1081 BlockHash: "123", 1082 }, 1083 }, 1084 { 1085 name: "searchrawtransactions", 1086 newCmd: func() (interface{}, error) { 1087 return btcjson.NewCmd("searchrawtransactions", "1Address") 1088 }, 1089 staticCmd: func() interface{} { 1090 return btcjson.NewSearchRawTransactionsCmd("1Address", nil, nil, nil, nil, nil, nil) 1091 }, 1092 marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address"],"id":1}`, 1093 unmarshalled: &btcjson.SearchRawTransactionsCmd{ 1094 Address: "1Address", 1095 Verbose: btcjson.Int(1), 1096 Skip: btcjson.Int(0), 1097 Count: btcjson.Int(100), 1098 VinExtra: btcjson.Int(0), 1099 Reverse: btcjson.Bool(false), 1100 FilterAddrs: nil, 1101 }, 1102 }, 1103 { 1104 name: "searchrawtransactions", 1105 newCmd: func() (interface{}, error) { 1106 return btcjson.NewCmd("searchrawtransactions", "1Address", 0) 1107 }, 1108 staticCmd: func() interface{} { 1109 return btcjson.NewSearchRawTransactionsCmd("1Address", 1110 btcjson.Int(0), nil, nil, nil, nil, nil) 1111 }, 1112 marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0],"id":1}`, 1113 unmarshalled: &btcjson.SearchRawTransactionsCmd{ 1114 Address: "1Address", 1115 Verbose: btcjson.Int(0), 1116 Skip: btcjson.Int(0), 1117 Count: btcjson.Int(100), 1118 VinExtra: btcjson.Int(0), 1119 Reverse: btcjson.Bool(false), 1120 FilterAddrs: nil, 1121 }, 1122 }, 1123 { 1124 name: "searchrawtransactions", 1125 newCmd: func() (interface{}, error) { 1126 return btcjson.NewCmd("searchrawtransactions", "1Address", 0, 5) 1127 }, 1128 staticCmd: func() interface{} { 1129 return btcjson.NewSearchRawTransactionsCmd("1Address", 1130 btcjson.Int(0), btcjson.Int(5), nil, nil, nil, nil) 1131 }, 1132 marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0,5],"id":1}`, 1133 unmarshalled: &btcjson.SearchRawTransactionsCmd{ 1134 Address: "1Address", 1135 Verbose: btcjson.Int(0), 1136 Skip: btcjson.Int(5), 1137 Count: btcjson.Int(100), 1138 VinExtra: btcjson.Int(0), 1139 Reverse: btcjson.Bool(false), 1140 FilterAddrs: nil, 1141 }, 1142 }, 1143 { 1144 name: "searchrawtransactions", 1145 newCmd: func() (interface{}, error) { 1146 return btcjson.NewCmd("searchrawtransactions", "1Address", 0, 5, 10) 1147 }, 1148 staticCmd: func() interface{} { 1149 return btcjson.NewSearchRawTransactionsCmd("1Address", 1150 btcjson.Int(0), btcjson.Int(5), btcjson.Int(10), nil, nil, nil) 1151 }, 1152 marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0,5,10],"id":1}`, 1153 unmarshalled: &btcjson.SearchRawTransactionsCmd{ 1154 Address: "1Address", 1155 Verbose: btcjson.Int(0), 1156 Skip: btcjson.Int(5), 1157 Count: btcjson.Int(10), 1158 VinExtra: btcjson.Int(0), 1159 Reverse: btcjson.Bool(false), 1160 FilterAddrs: nil, 1161 }, 1162 }, 1163 { 1164 name: "searchrawtransactions", 1165 newCmd: func() (interface{}, error) { 1166 return btcjson.NewCmd("searchrawtransactions", "1Address", 0, 5, 10, 1) 1167 }, 1168 staticCmd: func() interface{} { 1169 return btcjson.NewSearchRawTransactionsCmd("1Address", 1170 btcjson.Int(0), btcjson.Int(5), btcjson.Int(10), btcjson.Int(1), nil, nil) 1171 }, 1172 marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0,5,10,1],"id":1}`, 1173 unmarshalled: &btcjson.SearchRawTransactionsCmd{ 1174 Address: "1Address", 1175 Verbose: btcjson.Int(0), 1176 Skip: btcjson.Int(5), 1177 Count: btcjson.Int(10), 1178 VinExtra: btcjson.Int(1), 1179 Reverse: btcjson.Bool(false), 1180 FilterAddrs: nil, 1181 }, 1182 }, 1183 { 1184 name: "searchrawtransactions", 1185 newCmd: func() (interface{}, error) { 1186 return btcjson.NewCmd("searchrawtransactions", "1Address", 0, 5, 10, 1, true) 1187 }, 1188 staticCmd: func() interface{} { 1189 return btcjson.NewSearchRawTransactionsCmd("1Address", 1190 btcjson.Int(0), btcjson.Int(5), btcjson.Int(10), btcjson.Int(1), btcjson.Bool(true), nil) 1191 }, 1192 marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0,5,10,1,true],"id":1}`, 1193 unmarshalled: &btcjson.SearchRawTransactionsCmd{ 1194 Address: "1Address", 1195 Verbose: btcjson.Int(0), 1196 Skip: btcjson.Int(5), 1197 Count: btcjson.Int(10), 1198 VinExtra: btcjson.Int(1), 1199 Reverse: btcjson.Bool(true), 1200 FilterAddrs: nil, 1201 }, 1202 }, 1203 { 1204 name: "searchrawtransactions", 1205 newCmd: func() (interface{}, error) { 1206 return btcjson.NewCmd("searchrawtransactions", "1Address", 0, 5, 10, 1, true, []string{"1Address"}) 1207 }, 1208 staticCmd: func() interface{} { 1209 return btcjson.NewSearchRawTransactionsCmd("1Address", 1210 btcjson.Int(0), btcjson.Int(5), btcjson.Int(10), btcjson.Int(1), btcjson.Bool(true), &[]string{"1Address"}) 1211 }, 1212 marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0,5,10,1,true,["1Address"]],"id":1}`, 1213 unmarshalled: &btcjson.SearchRawTransactionsCmd{ 1214 Address: "1Address", 1215 Verbose: btcjson.Int(0), 1216 Skip: btcjson.Int(5), 1217 Count: btcjson.Int(10), 1218 VinExtra: btcjson.Int(1), 1219 Reverse: btcjson.Bool(true), 1220 FilterAddrs: &[]string{"1Address"}, 1221 }, 1222 }, 1223 { 1224 name: "searchrawtransactions", 1225 newCmd: func() (interface{}, error) { 1226 return btcjson.NewCmd("searchrawtransactions", "1Address", 0, 5, 10, "null", true, []string{"1Address"}) 1227 }, 1228 staticCmd: func() interface{} { 1229 return btcjson.NewSearchRawTransactionsCmd("1Address", 1230 btcjson.Int(0), btcjson.Int(5), btcjson.Int(10), nil, btcjson.Bool(true), &[]string{"1Address"}) 1231 }, 1232 marshalled: `{"jsonrpc":"1.0","method":"searchrawtransactions","params":["1Address",0,5,10,null,true,["1Address"]],"id":1}`, 1233 unmarshalled: &btcjson.SearchRawTransactionsCmd{ 1234 Address: "1Address", 1235 Verbose: btcjson.Int(0), 1236 Skip: btcjson.Int(5), 1237 Count: btcjson.Int(10), 1238 VinExtra: nil, 1239 Reverse: btcjson.Bool(true), 1240 FilterAddrs: &[]string{"1Address"}, 1241 }, 1242 }, 1243 { 1244 name: "sendrawtransaction", 1245 newCmd: func() (interface{}, error) { 1246 return btcjson.NewCmd("sendrawtransaction", "1122", &btcjson.AllowHighFeesOrMaxFeeRate{}) 1247 }, 1248 staticCmd: func() interface{} { 1249 return btcjson.NewSendRawTransactionCmd("1122", nil) 1250 }, 1251 marshalled: `{"jsonrpc":"1.0","method":"sendrawtransaction","params":["1122",false],"id":1}`, 1252 unmarshalled: &btcjson.SendRawTransactionCmd{ 1253 HexTx: "1122", 1254 FeeSetting: &btcjson.AllowHighFeesOrMaxFeeRate{ 1255 Value: btcjson.Bool(false), 1256 }, 1257 }, 1258 }, 1259 { 1260 name: "sendrawtransaction optional", 1261 newCmd: func() (interface{}, error) { 1262 return btcjson.NewCmd("sendrawtransaction", "1122", &btcjson.AllowHighFeesOrMaxFeeRate{Value: btcjson.Bool(false)}) 1263 }, 1264 staticCmd: func() interface{} { 1265 return btcjson.NewSendRawTransactionCmd("1122", btcjson.Bool(false)) 1266 }, 1267 marshalled: `{"jsonrpc":"1.0","method":"sendrawtransaction","params":["1122",false],"id":1}`, 1268 unmarshalled: &btcjson.SendRawTransactionCmd{ 1269 HexTx: "1122", 1270 FeeSetting: &btcjson.AllowHighFeesOrMaxFeeRate{ 1271 Value: btcjson.Bool(false), 1272 }, 1273 }, 1274 }, 1275 { 1276 name: "sendrawtransaction optional, bitcoind >= 0.19.0", 1277 newCmd: func() (interface{}, error) { 1278 return btcjson.NewCmd("sendrawtransaction", "1122", &btcjson.AllowHighFeesOrMaxFeeRate{Value: btcjson.Int32(1234)}) 1279 }, 1280 staticCmd: func() interface{} { 1281 return btcjson.NewBitcoindSendRawTransactionCmd("1122", 1234) 1282 }, 1283 marshalled: `{"jsonrpc":"1.0","method":"sendrawtransaction","params":["1122",1234],"id":1}`, 1284 unmarshalled: &btcjson.SendRawTransactionCmd{ 1285 HexTx: "1122", 1286 FeeSetting: &btcjson.AllowHighFeesOrMaxFeeRate{ 1287 Value: btcjson.Int32(1234), 1288 }, 1289 }, 1290 }, 1291 { 1292 name: "setgenerate", 1293 newCmd: func() (interface{}, error) { 1294 return btcjson.NewCmd("setgenerate", true) 1295 }, 1296 staticCmd: func() interface{} { 1297 return btcjson.NewSetGenerateCmd(true, nil) 1298 }, 1299 marshalled: `{"jsonrpc":"1.0","method":"setgenerate","params":[true],"id":1}`, 1300 unmarshalled: &btcjson.SetGenerateCmd{ 1301 Generate: true, 1302 GenProcLimit: btcjson.Int(-1), 1303 }, 1304 }, 1305 { 1306 name: "setgenerate optional", 1307 newCmd: func() (interface{}, error) { 1308 return btcjson.NewCmd("setgenerate", true, 6) 1309 }, 1310 staticCmd: func() interface{} { 1311 return btcjson.NewSetGenerateCmd(true, btcjson.Int(6)) 1312 }, 1313 marshalled: `{"jsonrpc":"1.0","method":"setgenerate","params":[true,6],"id":1}`, 1314 unmarshalled: &btcjson.SetGenerateCmd{ 1315 Generate: true, 1316 GenProcLimit: btcjson.Int(6), 1317 }, 1318 }, 1319 { 1320 name: "signmessagewithprivkey", 1321 newCmd: func() (interface{}, error) { 1322 return btcjson.NewCmd("signmessagewithprivkey", "5Hue", "Hey") 1323 }, 1324 staticCmd: func() interface{} { 1325 return btcjson.NewSignMessageWithPrivKey("5Hue", "Hey") 1326 }, 1327 marshalled: `{"jsonrpc":"1.0","method":"signmessagewithprivkey","params":["5Hue","Hey"],"id":1}`, 1328 unmarshalled: &btcjson.SignMessageWithPrivKeyCmd{ 1329 PrivKey: "5Hue", 1330 Message: "Hey", 1331 }, 1332 }, 1333 { 1334 name: "stop", 1335 newCmd: func() (interface{}, error) { 1336 return btcjson.NewCmd("stop") 1337 }, 1338 staticCmd: func() interface{} { 1339 return btcjson.NewStopCmd() 1340 }, 1341 marshalled: `{"jsonrpc":"1.0","method":"stop","params":[],"id":1}`, 1342 unmarshalled: &btcjson.StopCmd{}, 1343 }, 1344 { 1345 name: "submitblock", 1346 newCmd: func() (interface{}, error) { 1347 return btcjson.NewCmd("submitblock", "112233") 1348 }, 1349 staticCmd: func() interface{} { 1350 return btcjson.NewSubmitBlockCmd("112233", nil) 1351 }, 1352 marshalled: `{"jsonrpc":"1.0","method":"submitblock","params":["112233"],"id":1}`, 1353 unmarshalled: &btcjson.SubmitBlockCmd{ 1354 HexBlock: "112233", 1355 Options: nil, 1356 }, 1357 }, 1358 { 1359 name: "submitblock optional", 1360 newCmd: func() (interface{}, error) { 1361 return btcjson.NewCmd("submitblock", "112233", `{"workid":"12345"}`) 1362 }, 1363 staticCmd: func() interface{} { 1364 options := btcjson.SubmitBlockOptions{ 1365 WorkID: "12345", 1366 } 1367 return btcjson.NewSubmitBlockCmd("112233", &options) 1368 }, 1369 marshalled: `{"jsonrpc":"1.0","method":"submitblock","params":["112233",{"workid":"12345"}],"id":1}`, 1370 unmarshalled: &btcjson.SubmitBlockCmd{ 1371 HexBlock: "112233", 1372 Options: &btcjson.SubmitBlockOptions{ 1373 WorkID: "12345", 1374 }, 1375 }, 1376 }, 1377 { 1378 name: "uptime", 1379 newCmd: func() (interface{}, error) { 1380 return btcjson.NewCmd("uptime") 1381 }, 1382 staticCmd: func() interface{} { 1383 return btcjson.NewUptimeCmd() 1384 }, 1385 marshalled: `{"jsonrpc":"1.0","method":"uptime","params":[],"id":1}`, 1386 unmarshalled: &btcjson.UptimeCmd{}, 1387 }, 1388 { 1389 name: "validateaddress", 1390 newCmd: func() (interface{}, error) { 1391 return btcjson.NewCmd("validateaddress", "1Address") 1392 }, 1393 staticCmd: func() interface{} { 1394 return btcjson.NewValidateAddressCmd("1Address") 1395 }, 1396 marshalled: `{"jsonrpc":"1.0","method":"validateaddress","params":["1Address"],"id":1}`, 1397 unmarshalled: &btcjson.ValidateAddressCmd{ 1398 Address: "1Address", 1399 }, 1400 }, 1401 { 1402 name: "verifychain", 1403 newCmd: func() (interface{}, error) { 1404 return btcjson.NewCmd("verifychain") 1405 }, 1406 staticCmd: func() interface{} { 1407 return btcjson.NewVerifyChainCmd(nil, nil) 1408 }, 1409 marshalled: `{"jsonrpc":"1.0","method":"verifychain","params":[],"id":1}`, 1410 unmarshalled: &btcjson.VerifyChainCmd{ 1411 CheckLevel: btcjson.Int32(3), 1412 CheckDepth: btcjson.Int32(288), 1413 }, 1414 }, 1415 { 1416 name: "verifychain optional1", 1417 newCmd: func() (interface{}, error) { 1418 return btcjson.NewCmd("verifychain", 2) 1419 }, 1420 staticCmd: func() interface{} { 1421 return btcjson.NewVerifyChainCmd(btcjson.Int32(2), nil) 1422 }, 1423 marshalled: `{"jsonrpc":"1.0","method":"verifychain","params":[2],"id":1}`, 1424 unmarshalled: &btcjson.VerifyChainCmd{ 1425 CheckLevel: btcjson.Int32(2), 1426 CheckDepth: btcjson.Int32(288), 1427 }, 1428 }, 1429 { 1430 name: "verifychain optional2", 1431 newCmd: func() (interface{}, error) { 1432 return btcjson.NewCmd("verifychain", 2, 500) 1433 }, 1434 staticCmd: func() interface{} { 1435 return btcjson.NewVerifyChainCmd(btcjson.Int32(2), btcjson.Int32(500)) 1436 }, 1437 marshalled: `{"jsonrpc":"1.0","method":"verifychain","params":[2,500],"id":1}`, 1438 unmarshalled: &btcjson.VerifyChainCmd{ 1439 CheckLevel: btcjson.Int32(2), 1440 CheckDepth: btcjson.Int32(500), 1441 }, 1442 }, 1443 { 1444 name: "verifymessage", 1445 newCmd: func() (interface{}, error) { 1446 return btcjson.NewCmd("verifymessage", "1Address", "301234", "test") 1447 }, 1448 staticCmd: func() interface{} { 1449 return btcjson.NewVerifyMessageCmd("1Address", "301234", "test") 1450 }, 1451 marshalled: `{"jsonrpc":"1.0","method":"verifymessage","params":["1Address","301234","test"],"id":1}`, 1452 unmarshalled: &btcjson.VerifyMessageCmd{ 1453 Address: "1Address", 1454 Signature: "301234", 1455 Message: "test", 1456 }, 1457 }, 1458 { 1459 name: "verifytxoutproof", 1460 newCmd: func() (interface{}, error) { 1461 return btcjson.NewCmd("verifytxoutproof", "test") 1462 }, 1463 staticCmd: func() interface{} { 1464 return btcjson.NewVerifyTxOutProofCmd("test") 1465 }, 1466 marshalled: `{"jsonrpc":"1.0","method":"verifytxoutproof","params":["test"],"id":1}`, 1467 unmarshalled: &btcjson.VerifyTxOutProofCmd{ 1468 Proof: "test", 1469 }, 1470 }, 1471 { 1472 name: "getdescriptorinfo", 1473 newCmd: func() (interface{}, error) { 1474 return btcjson.NewCmd("getdescriptorinfo", "123") 1475 }, 1476 staticCmd: func() interface{} { 1477 return btcjson.NewGetDescriptorInfoCmd("123") 1478 }, 1479 marshalled: `{"jsonrpc":"1.0","method":"getdescriptorinfo","params":["123"],"id":1}`, 1480 unmarshalled: &btcjson.GetDescriptorInfoCmd{Descriptor: "123"}, 1481 }, 1482 } 1483 1484 t.Logf("Running %d tests", len(tests)) 1485 for i, test := range tests { 1486 // Marshal the command as created by the new static command 1487 // creation function. 1488 marshalled, err := btcjson.MarshalCmd(btcjson.RpcVersion1, testID, test.staticCmd()) 1489 if err != nil { 1490 t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i, 1491 test.name, err) 1492 continue 1493 } 1494 1495 if !bytes.Equal(marshalled, []byte(test.marshalled)) { 1496 t.Errorf("Test #%d (%s) unexpected marshalled data - "+ 1497 "got %s, want %s", i, test.name, marshalled, 1498 test.marshalled) 1499 t.Errorf("\n%s\n%s", marshalled, test.marshalled) 1500 continue 1501 } 1502 1503 // Ensure the command is created without error via the generic 1504 // new command creation function. 1505 cmd, err := test.newCmd() 1506 if err != nil { 1507 t.Errorf("Test #%d (%s) unexpected NewCmd error: %v ", 1508 i, test.name, err) 1509 } 1510 1511 // Marshal the command as created by the generic new command 1512 // creation function. 1513 marshalled, err = btcjson.MarshalCmd(btcjson.RpcVersion1, testID, cmd) 1514 if err != nil { 1515 t.Errorf("MarshalCmd #%d (%s) unexpected error: %v", i, 1516 test.name, err) 1517 continue 1518 } 1519 1520 if !bytes.Equal(marshalled, []byte(test.marshalled)) { 1521 t.Errorf("Test #%d (%s) unexpected marshalled data - "+ 1522 "got %s, want %s", i, test.name, marshalled, 1523 test.marshalled) 1524 continue 1525 } 1526 1527 var request btcjson.Request 1528 if err := json.Unmarshal(marshalled, &request); err != nil { 1529 t.Errorf("Test #%d (%s) unexpected error while "+ 1530 "unmarshalling JSON-RPC request: %v", i, 1531 test.name, err) 1532 continue 1533 } 1534 1535 cmd, err = btcjson.UnmarshalCmd(&request) 1536 if err != nil { 1537 t.Errorf("UnmarshalCmd #%d (%s) unexpected error: %v", i, 1538 test.name, err) 1539 continue 1540 } 1541 1542 if !reflect.DeepEqual(cmd, test.unmarshalled) { 1543 t.Errorf("Test #%d (%s) unexpected unmarshalled command "+ 1544 "- got %s, want %s", i, test.name, 1545 fmt.Sprintf("(%T) %+[1]v", cmd), 1546 fmt.Sprintf("(%T) %+[1]v\n", test.unmarshalled)) 1547 continue 1548 } 1549 } 1550 } 1551 1552 // TestChainSvrCmdErrors ensures any errors that occur in the command during 1553 // custom mashal and unmarshal are as expected. 1554 func TestChainSvrCmdErrors(t *testing.T) { 1555 t.Parallel() 1556 1557 tests := []struct { 1558 name string 1559 result interface{} 1560 marshalled string 1561 err error 1562 }{ 1563 { 1564 name: "template request with invalid type", 1565 result: &btcjson.TemplateRequest{}, 1566 marshalled: `{"mode":1}`, 1567 err: &json.UnmarshalTypeError{}, 1568 }, 1569 { 1570 name: "invalid template request sigoplimit field", 1571 result: &btcjson.TemplateRequest{}, 1572 marshalled: `{"sigoplimit":"invalid"}`, 1573 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType}, 1574 }, 1575 { 1576 name: "invalid template request sizelimit field", 1577 result: &btcjson.TemplateRequest{}, 1578 marshalled: `{"sizelimit":"invalid"}`, 1579 err: btcjson.Error{ErrorCode: btcjson.ErrInvalidType}, 1580 }, 1581 } 1582 1583 t.Logf("Running %d tests", len(tests)) 1584 for i, test := range tests { 1585 err := json.Unmarshal([]byte(test.marshalled), &test.result) 1586 if reflect.TypeOf(err) != reflect.TypeOf(test.err) { 1587 t.Errorf("Test #%d (%s) wrong error - got %T (%v), "+ 1588 "want %T", i, test.name, err, err, test.err) 1589 continue 1590 } 1591 1592 if terr, ok := test.err.(btcjson.Error); ok { 1593 gotErrorCode := err.(btcjson.Error).ErrorCode 1594 if gotErrorCode != terr.ErrorCode { 1595 t.Errorf("Test #%d (%s) mismatched error code "+ 1596 "- got %v (%v), want %v", i, test.name, 1597 gotErrorCode, terr, terr.ErrorCode) 1598 continue 1599 } 1600 } 1601 } 1602 }