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