github.com/btcsuite/btcd@v0.24.0/rpcserver.go (about) 1 // Copyright (c) 2013-2017 The btcsuite developers 2 // Copyright (c) 2015-2017 The Decred developers 3 // Use of this source code is governed by an ISC 4 // license that can be found in the LICENSE file. 5 6 package main 7 8 import ( 9 "bytes" 10 "crypto/sha256" 11 "crypto/subtle" 12 "encoding/base64" 13 "encoding/hex" 14 "encoding/json" 15 "errors" 16 "fmt" 17 "io" 18 "io/ioutil" 19 "math/big" 20 "math/rand" 21 "net" 22 "net/http" 23 "os" 24 "strconv" 25 "strings" 26 "sync" 27 "sync/atomic" 28 "time" 29 30 "github.com/btcsuite/btcd/blockchain" 31 "github.com/btcsuite/btcd/blockchain/indexers" 32 "github.com/btcsuite/btcd/btcec/v2/ecdsa" 33 "github.com/btcsuite/btcd/btcjson" 34 "github.com/btcsuite/btcd/btcutil" 35 "github.com/btcsuite/btcd/chaincfg" 36 "github.com/btcsuite/btcd/chaincfg/chainhash" 37 "github.com/btcsuite/btcd/database" 38 "github.com/btcsuite/btcd/mempool" 39 "github.com/btcsuite/btcd/mining" 40 "github.com/btcsuite/btcd/mining/cpuminer" 41 "github.com/btcsuite/btcd/peer" 42 "github.com/btcsuite/btcd/txscript" 43 "github.com/btcsuite/btcd/wire" 44 "github.com/btcsuite/websocket" 45 ) 46 47 // API version constants 48 const ( 49 jsonrpcSemverString = "1.3.0" 50 jsonrpcSemverMajor = 1 51 jsonrpcSemverMinor = 3 52 jsonrpcSemverPatch = 0 53 ) 54 55 const ( 56 // rpcAuthTimeoutSeconds is the number of seconds a connection to the 57 // RPC server is allowed to stay open without authenticating before it 58 // is closed. 59 rpcAuthTimeoutSeconds = 10 60 61 // uint256Size is the number of bytes needed to represent an unsigned 62 // 256-bit integer. 63 uint256Size = 32 64 65 // gbtNonceRange is two 32-bit big-endian hexadecimal integers which 66 // represent the valid ranges of nonces returned by the getblocktemplate 67 // RPC. 68 gbtNonceRange = "00000000ffffffff" 69 70 // gbtRegenerateSeconds is the number of seconds that must pass before 71 // a new template is generated when the previous block hash has not 72 // changed and there have been changes to the available transactions 73 // in the memory pool. 74 gbtRegenerateSeconds = 60 75 76 // maxProtocolVersion is the max protocol version the server supports. 77 maxProtocolVersion = 70002 78 ) 79 80 var ( 81 // gbtMutableFields are the manipulations the server allows to be made 82 // to block templates generated by the getblocktemplate RPC. It is 83 // declared here to avoid the overhead of creating the slice on every 84 // invocation for constant data. 85 gbtMutableFields = []string{ 86 "time", "transactions/add", "prevblock", "coinbase/append", 87 } 88 89 // gbtCoinbaseAux describes additional data that miners should include 90 // in the coinbase signature script. It is declared here to avoid the 91 // overhead of creating a new object on every invocation for constant 92 // data. 93 gbtCoinbaseAux = &btcjson.GetBlockTemplateResultAux{ 94 Flags: hex.EncodeToString(builderScript(txscript. 95 NewScriptBuilder(). 96 AddData([]byte(mining.CoinbaseFlags)))), 97 } 98 99 // gbtCapabilities describes additional capabilities returned with a 100 // block template generated by the getblocktemplate RPC. It is 101 // declared here to avoid the overhead of creating the slice on every 102 // invocation for constant data. 103 gbtCapabilities = []string{"proposal"} 104 105 // JSON 2.0 batched request prefix 106 batchedRequestPrefix = []byte("[") 107 ) 108 109 // Errors 110 var ( 111 // ErrRPCUnimplemented is an error returned to RPC clients when the 112 // provided command is recognized, but not implemented. 113 ErrRPCUnimplemented = &btcjson.RPCError{ 114 Code: btcjson.ErrRPCUnimplemented, 115 Message: "Command unimplemented", 116 } 117 118 // ErrRPCNoWallet is an error returned to RPC clients when the provided 119 // command is recognized as a wallet command. 120 ErrRPCNoWallet = &btcjson.RPCError{ 121 Code: btcjson.ErrRPCNoWallet, 122 Message: "This implementation does not implement wallet commands", 123 } 124 ) 125 126 type commandHandler func(*rpcServer, interface{}, <-chan struct{}) (interface{}, error) 127 128 // rpcHandlers maps RPC command strings to appropriate handler functions. 129 // This is set by init because help references rpcHandlers and thus causes 130 // a dependency loop. 131 var rpcHandlers map[string]commandHandler 132 var rpcHandlersBeforeInit = map[string]commandHandler{ 133 "addnode": handleAddNode, 134 "createrawtransaction": handleCreateRawTransaction, 135 "debuglevel": handleDebugLevel, 136 "decoderawtransaction": handleDecodeRawTransaction, 137 "decodescript": handleDecodeScript, 138 "estimatefee": handleEstimateFee, 139 "generate": handleGenerate, 140 "getaddednodeinfo": handleGetAddedNodeInfo, 141 "getbestblock": handleGetBestBlock, 142 "getbestblockhash": handleGetBestBlockHash, 143 "getblock": handleGetBlock, 144 "getblockchaininfo": handleGetBlockChainInfo, 145 "getblockcount": handleGetBlockCount, 146 "getblockhash": handleGetBlockHash, 147 "getblockheader": handleGetBlockHeader, 148 "getblocktemplate": handleGetBlockTemplate, 149 "getchaintips": handleGetChainTips, 150 "getcfilter": handleGetCFilter, 151 "getcfilterheader": handleGetCFilterHeader, 152 "getconnectioncount": handleGetConnectionCount, 153 "getcurrentnet": handleGetCurrentNet, 154 "getdifficulty": handleGetDifficulty, 155 "getgenerate": handleGetGenerate, 156 "gethashespersec": handleGetHashesPerSec, 157 "getheaders": handleGetHeaders, 158 "getinfo": handleGetInfo, 159 "getmempoolinfo": handleGetMempoolInfo, 160 "getmininginfo": handleGetMiningInfo, 161 "getnettotals": handleGetNetTotals, 162 "getnetworkhashps": handleGetNetworkHashPS, 163 "getnodeaddresses": handleGetNodeAddresses, 164 "getpeerinfo": handleGetPeerInfo, 165 "getrawmempool": handleGetRawMempool, 166 "getrawtransaction": handleGetRawTransaction, 167 "gettxout": handleGetTxOut, 168 "help": handleHelp, 169 "node": handleNode, 170 "ping": handlePing, 171 "searchrawtransactions": handleSearchRawTransactions, 172 "sendrawtransaction": handleSendRawTransaction, 173 "setgenerate": handleSetGenerate, 174 "signmessagewithprivkey": handleSignMessageWithPrivKey, 175 "stop": handleStop, 176 "submitblock": handleSubmitBlock, 177 "uptime": handleUptime, 178 "validateaddress": handleValidateAddress, 179 "verifychain": handleVerifyChain, 180 "verifymessage": handleVerifyMessage, 181 "version": handleVersion, 182 } 183 184 // list of commands that we recognize, but for which btcd has no support because 185 // it lacks support for wallet functionality. For these commands the user 186 // should ask a connected instance of btcwallet. 187 var rpcAskWallet = map[string]struct{}{ 188 "addmultisigaddress": {}, 189 "backupwallet": {}, 190 "createencryptedwallet": {}, 191 "createmultisig": {}, 192 "dumpprivkey": {}, 193 "dumpwallet": {}, 194 "encryptwallet": {}, 195 "getaccount": {}, 196 "getaccountaddress": {}, 197 "getaddressesbyaccount": {}, 198 "getbalance": {}, 199 "getnewaddress": {}, 200 "getrawchangeaddress": {}, 201 "getreceivedbyaccount": {}, 202 "getreceivedbyaddress": {}, 203 "gettransaction": {}, 204 "gettxoutsetinfo": {}, 205 "getunconfirmedbalance": {}, 206 "getwalletinfo": {}, 207 "importprivkey": {}, 208 "importwallet": {}, 209 "keypoolrefill": {}, 210 "listaccounts": {}, 211 "listaddressgroupings": {}, 212 "listlockunspent": {}, 213 "listreceivedbyaccount": {}, 214 "listreceivedbyaddress": {}, 215 "listsinceblock": {}, 216 "listtransactions": {}, 217 "listunspent": {}, 218 "lockunspent": {}, 219 "move": {}, 220 "sendfrom": {}, 221 "sendmany": {}, 222 "sendtoaddress": {}, 223 "setaccount": {}, 224 "settxfee": {}, 225 "signmessage": {}, 226 "signrawtransaction": {}, 227 "walletlock": {}, 228 "walletpassphrase": {}, 229 "walletpassphrasechange": {}, 230 } 231 232 // Commands that are currently unimplemented, but should ultimately be. 233 var rpcUnimplemented = map[string]struct{}{ 234 "estimatepriority": {}, 235 "getmempoolentry": {}, 236 "getnetworkinfo": {}, 237 "getwork": {}, 238 "invalidateblock": {}, 239 "preciousblock": {}, 240 "reconsiderblock": {}, 241 } 242 243 // Commands that are available to a limited user 244 var rpcLimited = map[string]struct{}{ 245 // Websockets commands 246 "loadtxfilter": {}, 247 "notifyblocks": {}, 248 "notifynewtransactions": {}, 249 "notifyreceived": {}, 250 "notifyspent": {}, 251 "rescan": {}, 252 "rescanblocks": {}, 253 "session": {}, 254 255 // Websockets AND HTTP/S commands 256 "help": {}, 257 258 // HTTP/S-only commands 259 "createrawtransaction": {}, 260 "decoderawtransaction": {}, 261 "decodescript": {}, 262 "estimatefee": {}, 263 "getbestblock": {}, 264 "getbestblockhash": {}, 265 "getblock": {}, 266 "getblockcount": {}, 267 "getblockhash": {}, 268 "getblockheader": {}, 269 "getchaintips": {}, 270 "getcfilter": {}, 271 "getcfilterheader": {}, 272 "getcurrentnet": {}, 273 "getdifficulty": {}, 274 "getheaders": {}, 275 "getinfo": {}, 276 "getnettotals": {}, 277 "getnetworkhashps": {}, 278 "getrawmempool": {}, 279 "getrawtransaction": {}, 280 "gettxout": {}, 281 "searchrawtransactions": {}, 282 "sendrawtransaction": {}, 283 "submitblock": {}, 284 "uptime": {}, 285 "validateaddress": {}, 286 "verifymessage": {}, 287 "version": {}, 288 } 289 290 // builderScript is a convenience function which is used for hard-coded scripts 291 // built with the script builder. Any errors are converted to a panic since it 292 // is only, and must only, be used with hard-coded, and therefore, known good, 293 // scripts. 294 func builderScript(builder *txscript.ScriptBuilder) []byte { 295 script, err := builder.Script() 296 if err != nil { 297 panic(err) 298 } 299 return script 300 } 301 302 // internalRPCError is a convenience function to convert an internal error to 303 // an RPC error with the appropriate code set. It also logs the error to the 304 // RPC server subsystem since internal errors really should not occur. The 305 // context parameter is only used in the log message and may be empty if it's 306 // not needed. 307 func internalRPCError(errStr, context string) *btcjson.RPCError { 308 logStr := errStr 309 if context != "" { 310 logStr = context + ": " + errStr 311 } 312 rpcsLog.Error(logStr) 313 return btcjson.NewRPCError(btcjson.ErrRPCInternal.Code, errStr) 314 } 315 316 // rpcDecodeHexError is a convenience function for returning a nicely formatted 317 // RPC error which indicates the provided hex string failed to decode. 318 func rpcDecodeHexError(gotHex string) *btcjson.RPCError { 319 return btcjson.NewRPCError(btcjson.ErrRPCDecodeHexString, 320 fmt.Sprintf("Argument must be hexadecimal string (not %q)", 321 gotHex)) 322 } 323 324 // rpcNoTxInfoError is a convenience function for returning a nicely formatted 325 // RPC error which indicates there is no information available for the provided 326 // transaction hash. 327 func rpcNoTxInfoError(txHash *chainhash.Hash) *btcjson.RPCError { 328 return btcjson.NewRPCError(btcjson.ErrRPCNoTxInfo, 329 fmt.Sprintf("No information available about transaction %v", 330 txHash)) 331 } 332 333 // gbtWorkState houses state that is used in between multiple RPC invocations to 334 // getblocktemplate. 335 type gbtWorkState struct { 336 sync.Mutex 337 lastTxUpdate time.Time 338 lastGenerated time.Time 339 prevHash *chainhash.Hash 340 minTimestamp time.Time 341 template *mining.BlockTemplate 342 notifyMap map[chainhash.Hash]map[int64]chan struct{} 343 timeSource blockchain.MedianTimeSource 344 } 345 346 // newGbtWorkState returns a new instance of a gbtWorkState with all internal 347 // fields initialized and ready to use. 348 func newGbtWorkState(timeSource blockchain.MedianTimeSource) *gbtWorkState { 349 return &gbtWorkState{ 350 notifyMap: make(map[chainhash.Hash]map[int64]chan struct{}), 351 timeSource: timeSource, 352 } 353 } 354 355 // handleUnimplemented is the handler for commands that should ultimately be 356 // supported but are not yet implemented. 357 func handleUnimplemented(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 358 return nil, ErrRPCUnimplemented 359 } 360 361 // handleAskWallet is the handler for commands that are recognized as valid, but 362 // are unable to answer correctly since it involves wallet state. 363 // These commands will be implemented in btcwallet. 364 func handleAskWallet(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 365 return nil, ErrRPCNoWallet 366 } 367 368 // handleAddNode handles addnode commands. 369 func handleAddNode(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 370 c := cmd.(*btcjson.AddNodeCmd) 371 372 addr := normalizeAddress(c.Addr, s.cfg.ChainParams.DefaultPort) 373 var err error 374 switch c.SubCmd { 375 case "add": 376 err = s.cfg.ConnMgr.Connect(addr, true) 377 case "remove": 378 err = s.cfg.ConnMgr.RemoveByAddr(addr) 379 case "onetry": 380 err = s.cfg.ConnMgr.Connect(addr, false) 381 default: 382 return nil, &btcjson.RPCError{ 383 Code: btcjson.ErrRPCInvalidParameter, 384 Message: "invalid subcommand for addnode", 385 } 386 } 387 388 if err != nil { 389 return nil, &btcjson.RPCError{ 390 Code: btcjson.ErrRPCInvalidParameter, 391 Message: err.Error(), 392 } 393 } 394 395 // no data returned unless an error. 396 return nil, nil 397 } 398 399 // handleNode handles node commands. 400 func handleNode(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 401 c := cmd.(*btcjson.NodeCmd) 402 403 var addr string 404 var nodeID uint64 405 var errN, err error 406 params := s.cfg.ChainParams 407 switch c.SubCmd { 408 case "disconnect": 409 // If we have a valid uint disconnect by node id. Otherwise, 410 // attempt to disconnect by address, returning an error if a 411 // valid IP address is not supplied. 412 if nodeID, errN = strconv.ParseUint(c.Target, 10, 32); errN == nil { 413 err = s.cfg.ConnMgr.DisconnectByID(int32(nodeID)) 414 } else { 415 if _, _, errP := net.SplitHostPort(c.Target); errP == nil || net.ParseIP(c.Target) != nil { 416 addr = normalizeAddress(c.Target, params.DefaultPort) 417 err = s.cfg.ConnMgr.DisconnectByAddr(addr) 418 } else { 419 return nil, &btcjson.RPCError{ 420 Code: btcjson.ErrRPCInvalidParameter, 421 Message: "invalid address or node ID", 422 } 423 } 424 } 425 if err != nil && peerExists(s.cfg.ConnMgr, addr, int32(nodeID)) { 426 427 return nil, &btcjson.RPCError{ 428 Code: btcjson.ErrRPCMisc, 429 Message: "can't disconnect a permanent peer, use remove", 430 } 431 } 432 433 case "remove": 434 // If we have a valid uint disconnect by node id. Otherwise, 435 // attempt to disconnect by address, returning an error if a 436 // valid IP address is not supplied. 437 if nodeID, errN = strconv.ParseUint(c.Target, 10, 32); errN == nil { 438 err = s.cfg.ConnMgr.RemoveByID(int32(nodeID)) 439 } else { 440 if _, _, errP := net.SplitHostPort(c.Target); errP == nil || net.ParseIP(c.Target) != nil { 441 addr = normalizeAddress(c.Target, params.DefaultPort) 442 err = s.cfg.ConnMgr.RemoveByAddr(addr) 443 } else { 444 return nil, &btcjson.RPCError{ 445 Code: btcjson.ErrRPCInvalidParameter, 446 Message: "invalid address or node ID", 447 } 448 } 449 } 450 if err != nil && peerExists(s.cfg.ConnMgr, addr, int32(nodeID)) { 451 return nil, &btcjson.RPCError{ 452 Code: btcjson.ErrRPCMisc, 453 Message: "can't remove a temporary peer, use disconnect", 454 } 455 } 456 457 case "connect": 458 addr = normalizeAddress(c.Target, params.DefaultPort) 459 460 // Default to temporary connections. 461 subCmd := "temp" 462 if c.ConnectSubCmd != nil { 463 subCmd = *c.ConnectSubCmd 464 } 465 466 switch subCmd { 467 case "perm", "temp": 468 err = s.cfg.ConnMgr.Connect(addr, subCmd == "perm") 469 default: 470 return nil, &btcjson.RPCError{ 471 Code: btcjson.ErrRPCInvalidParameter, 472 Message: "invalid subcommand for node connect", 473 } 474 } 475 default: 476 return nil, &btcjson.RPCError{ 477 Code: btcjson.ErrRPCInvalidParameter, 478 Message: "invalid subcommand for node", 479 } 480 } 481 482 if err != nil { 483 return nil, &btcjson.RPCError{ 484 Code: btcjson.ErrRPCInvalidParameter, 485 Message: err.Error(), 486 } 487 } 488 489 // no data returned unless an error. 490 return nil, nil 491 } 492 493 // peerExists determines if a certain peer is currently connected given 494 // information about all currently connected peers. Peer existence is 495 // determined using either a target address or node id. 496 func peerExists(connMgr rpcserverConnManager, addr string, nodeID int32) bool { 497 for _, p := range connMgr.ConnectedPeers() { 498 if p.ToPeer().ID() == nodeID || p.ToPeer().Addr() == addr { 499 return true 500 } 501 } 502 return false 503 } 504 505 // messageToHex serializes a message to the wire protocol encoding using the 506 // latest protocol version and returns a hex-encoded string of the result. 507 func messageToHex(msg wire.Message) (string, error) { 508 var buf bytes.Buffer 509 if err := msg.BtcEncode(&buf, maxProtocolVersion, wire.WitnessEncoding); err != nil { 510 context := fmt.Sprintf("Failed to encode msg of type %T", msg) 511 return "", internalRPCError(err.Error(), context) 512 } 513 514 return hex.EncodeToString(buf.Bytes()), nil 515 } 516 517 // handleCreateRawTransaction handles createrawtransaction commands. 518 func handleCreateRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 519 c := cmd.(*btcjson.CreateRawTransactionCmd) 520 521 // Validate the locktime, if given. 522 if c.LockTime != nil && 523 (*c.LockTime < 0 || *c.LockTime > int64(wire.MaxTxInSequenceNum)) { 524 return nil, &btcjson.RPCError{ 525 Code: btcjson.ErrRPCInvalidParameter, 526 Message: "Locktime out of range", 527 } 528 } 529 530 // Add all transaction inputs to a new transaction after performing 531 // some validity checks. 532 mtx := wire.NewMsgTx(wire.TxVersion) 533 for _, input := range c.Inputs { 534 txHash, err := chainhash.NewHashFromStr(input.Txid) 535 if err != nil { 536 return nil, rpcDecodeHexError(input.Txid) 537 } 538 539 prevOut := wire.NewOutPoint(txHash, input.Vout) 540 txIn := wire.NewTxIn(prevOut, []byte{}, nil) 541 if c.LockTime != nil && *c.LockTime != 0 { 542 txIn.Sequence = wire.MaxTxInSequenceNum - 1 543 } 544 mtx.AddTxIn(txIn) 545 } 546 547 // Add all transaction outputs to the transaction after performing 548 // some validity checks. 549 params := s.cfg.ChainParams 550 for encodedAddr, amount := range c.Amounts { 551 // Ensure amount is in the valid range for monetary amounts. 552 if amount <= 0 || amount*btcutil.SatoshiPerBitcoin > btcutil.MaxSatoshi { 553 return nil, &btcjson.RPCError{ 554 Code: btcjson.ErrRPCType, 555 Message: "Invalid amount", 556 } 557 } 558 559 // Decode the provided address. 560 addr, err := btcutil.DecodeAddress(encodedAddr, params) 561 if err != nil { 562 return nil, &btcjson.RPCError{ 563 Code: btcjson.ErrRPCInvalidAddressOrKey, 564 Message: "Invalid address or key: " + err.Error(), 565 } 566 } 567 568 // Ensure the address is one of the supported types and that 569 // the network encoded with the address matches the network the 570 // server is currently on. 571 switch addr.(type) { 572 case *btcutil.AddressPubKeyHash: 573 case *btcutil.AddressScriptHash: 574 default: 575 return nil, &btcjson.RPCError{ 576 Code: btcjson.ErrRPCInvalidAddressOrKey, 577 Message: "Invalid address or key", 578 } 579 } 580 if !addr.IsForNet(params) { 581 return nil, &btcjson.RPCError{ 582 Code: btcjson.ErrRPCInvalidAddressOrKey, 583 Message: "Invalid address: " + encodedAddr + 584 " is for the wrong network", 585 } 586 } 587 588 // Create a new script which pays to the provided address. 589 pkScript, err := txscript.PayToAddrScript(addr) 590 if err != nil { 591 context := "Failed to generate pay-to-address script" 592 return nil, internalRPCError(err.Error(), context) 593 } 594 595 // Convert the amount to satoshi. 596 satoshi, err := btcutil.NewAmount(amount) 597 if err != nil { 598 context := "Failed to convert amount" 599 return nil, internalRPCError(err.Error(), context) 600 } 601 602 txOut := wire.NewTxOut(int64(satoshi), pkScript) 603 mtx.AddTxOut(txOut) 604 } 605 606 // Set the Locktime, if given. 607 if c.LockTime != nil { 608 mtx.LockTime = uint32(*c.LockTime) 609 } 610 611 // Return the serialized and hex-encoded transaction. Note that this 612 // is intentionally not directly returning because the first return 613 // value is a string and it would result in returning an empty string to 614 // the client instead of nothing (nil) in the case of an error. 615 mtxHex, err := messageToHex(mtx) 616 if err != nil { 617 return nil, err 618 } 619 return mtxHex, nil 620 } 621 622 // handleDebugLevel handles debuglevel commands. 623 func handleDebugLevel(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 624 c := cmd.(*btcjson.DebugLevelCmd) 625 626 // Special show command to list supported subsystems. 627 if c.LevelSpec == "show" { 628 return fmt.Sprintf("Supported subsystems %v", 629 supportedSubsystems()), nil 630 } 631 632 err := parseAndSetDebugLevels(c.LevelSpec) 633 if err != nil { 634 return nil, &btcjson.RPCError{ 635 Code: btcjson.ErrRPCInvalidParams.Code, 636 Message: err.Error(), 637 } 638 } 639 640 return "Done.", nil 641 } 642 643 // witnessToHex formats the passed witness stack as a slice of hex-encoded 644 // strings to be used in a JSON response. 645 func witnessToHex(witness wire.TxWitness) []string { 646 // Ensure nil is returned when there are no entries versus an empty 647 // slice so it can properly be omitted as necessary. 648 if len(witness) == 0 { 649 return nil 650 } 651 652 result := make([]string, 0, len(witness)) 653 for _, wit := range witness { 654 result = append(result, hex.EncodeToString(wit)) 655 } 656 657 return result 658 } 659 660 // createVinList returns a slice of JSON objects for the inputs of the passed 661 // transaction. 662 func createVinList(mtx *wire.MsgTx) []btcjson.Vin { 663 // Coinbase transactions only have a single txin by definition. 664 vinList := make([]btcjson.Vin, len(mtx.TxIn)) 665 if blockchain.IsCoinBaseTx(mtx) { 666 txIn := mtx.TxIn[0] 667 vinList[0].Coinbase = hex.EncodeToString(txIn.SignatureScript) 668 vinList[0].Sequence = txIn.Sequence 669 vinList[0].Witness = witnessToHex(txIn.Witness) 670 return vinList 671 } 672 673 for i, txIn := range mtx.TxIn { 674 // The disassembled string will contain [error] inline 675 // if the script doesn't fully parse, so ignore the 676 // error here. 677 disbuf, _ := txscript.DisasmString(txIn.SignatureScript) 678 679 vinEntry := &vinList[i] 680 vinEntry.Txid = txIn.PreviousOutPoint.Hash.String() 681 vinEntry.Vout = txIn.PreviousOutPoint.Index 682 vinEntry.Sequence = txIn.Sequence 683 vinEntry.ScriptSig = &btcjson.ScriptSig{ 684 Asm: disbuf, 685 Hex: hex.EncodeToString(txIn.SignatureScript), 686 } 687 688 if mtx.HasWitness() { 689 vinEntry.Witness = witnessToHex(txIn.Witness) 690 } 691 } 692 693 return vinList 694 } 695 696 // createVoutList returns a slice of JSON objects for the outputs of the passed 697 // transaction. 698 func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params, filterAddrMap map[string]struct{}) []btcjson.Vout { 699 voutList := make([]btcjson.Vout, 0, len(mtx.TxOut)) 700 for i, v := range mtx.TxOut { 701 // The disassembled string will contain [error] inline if the 702 // script doesn't fully parse, so ignore the error here. 703 disbuf, _ := txscript.DisasmString(v.PkScript) 704 705 // Ignore the error here since an error means the script 706 // couldn't parse and there is no additional information about 707 // it anyways. 708 scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs( 709 v.PkScript, chainParams) 710 711 // Encode the addresses while checking if the address passes the 712 // filter when needed. 713 passesFilter := len(filterAddrMap) == 0 714 encodedAddrs := make([]string, len(addrs)) 715 for j, addr := range addrs { 716 encodedAddr := addr.EncodeAddress() 717 encodedAddrs[j] = encodedAddr 718 719 // No need to check the map again if the filter already 720 // passes. 721 if passesFilter { 722 continue 723 } 724 if _, exists := filterAddrMap[encodedAddr]; exists { 725 passesFilter = true 726 } 727 } 728 729 if !passesFilter { 730 continue 731 } 732 733 var vout btcjson.Vout 734 vout.N = uint32(i) 735 vout.Value = btcutil.Amount(v.Value).ToBTC() 736 vout.ScriptPubKey.Addresses = encodedAddrs 737 vout.ScriptPubKey.Asm = disbuf 738 vout.ScriptPubKey.Hex = hex.EncodeToString(v.PkScript) 739 vout.ScriptPubKey.Type = scriptClass.String() 740 vout.ScriptPubKey.ReqSigs = int32(reqSigs) 741 742 // Address is defined when there's a single well-defined 743 // receiver address. To spend the output a signature for this, 744 // and only this, address is required. 745 if len(encodedAddrs) == 1 && reqSigs <= 1 { 746 vout.ScriptPubKey.Address = encodedAddrs[0] 747 } 748 749 voutList = append(voutList, vout) 750 } 751 752 return voutList 753 } 754 755 // createTxRawResult converts the passed transaction and associated parameters 756 // to a raw transaction JSON object. 757 func createTxRawResult(chainParams *chaincfg.Params, mtx *wire.MsgTx, 758 txHash string, blkHeader *wire.BlockHeader, blkHash string, 759 blkHeight int32, chainHeight int32) (*btcjson.TxRawResult, error) { 760 761 mtxHex, err := messageToHex(mtx) 762 if err != nil { 763 return nil, err 764 } 765 766 txReply := &btcjson.TxRawResult{ 767 Hex: mtxHex, 768 Txid: txHash, 769 Hash: mtx.WitnessHash().String(), 770 Size: int32(mtx.SerializeSize()), 771 Vsize: int32(mempool.GetTxVirtualSize(btcutil.NewTx(mtx))), 772 Weight: int32(blockchain.GetTransactionWeight(btcutil.NewTx(mtx))), 773 Vin: createVinList(mtx), 774 Vout: createVoutList(mtx, chainParams, nil), 775 Version: uint32(mtx.Version), 776 LockTime: mtx.LockTime, 777 } 778 779 if blkHeader != nil { 780 // This is not a typo, they are identical in bitcoind as well. 781 txReply.Time = blkHeader.Timestamp.Unix() 782 txReply.Blocktime = blkHeader.Timestamp.Unix() 783 txReply.BlockHash = blkHash 784 txReply.Confirmations = uint64(1 + chainHeight - blkHeight) 785 } 786 787 return txReply, nil 788 } 789 790 // handleDecodeRawTransaction handles decoderawtransaction commands. 791 func handleDecodeRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 792 c := cmd.(*btcjson.DecodeRawTransactionCmd) 793 794 // Deserialize the transaction. 795 hexStr := c.HexTx 796 if len(hexStr)%2 != 0 { 797 hexStr = "0" + hexStr 798 } 799 serializedTx, err := hex.DecodeString(hexStr) 800 if err != nil { 801 return nil, rpcDecodeHexError(hexStr) 802 } 803 var mtx wire.MsgTx 804 err = mtx.Deserialize(bytes.NewReader(serializedTx)) 805 if err != nil { 806 return nil, &btcjson.RPCError{ 807 Code: btcjson.ErrRPCDeserialization, 808 Message: "TX decode failed: " + err.Error(), 809 } 810 } 811 812 // Create and return the result. 813 txReply := btcjson.TxRawDecodeResult{ 814 Txid: mtx.TxHash().String(), 815 Version: mtx.Version, 816 Locktime: mtx.LockTime, 817 Vin: createVinList(&mtx), 818 Vout: createVoutList(&mtx, s.cfg.ChainParams, nil), 819 } 820 return txReply, nil 821 } 822 823 // handleDecodeScript handles decodescript commands. 824 func handleDecodeScript(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 825 c := cmd.(*btcjson.DecodeScriptCmd) 826 827 // Convert the hex script to bytes. 828 hexStr := c.HexScript 829 if len(hexStr)%2 != 0 { 830 hexStr = "0" + hexStr 831 } 832 script, err := hex.DecodeString(hexStr) 833 if err != nil { 834 return nil, rpcDecodeHexError(hexStr) 835 } 836 837 // The disassembled string will contain [error] inline if the script 838 // doesn't fully parse, so ignore the error here. 839 disbuf, _ := txscript.DisasmString(script) 840 841 // Get information about the script. 842 // Ignore the error here since an error means the script couldn't parse 843 // and there is no additinal information about it anyways. 844 scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(script, 845 s.cfg.ChainParams) 846 addresses := make([]string, len(addrs)) 847 for i, addr := range addrs { 848 addresses[i] = addr.EncodeAddress() 849 } 850 851 // Convert the script itself to a pay-to-script-hash address. 852 p2sh, err := btcutil.NewAddressScriptHash(script, s.cfg.ChainParams) 853 if err != nil { 854 context := "Failed to convert script to pay-to-script-hash" 855 return nil, internalRPCError(err.Error(), context) 856 } 857 858 // Generate and return the reply. 859 reply := btcjson.DecodeScriptResult{ 860 Asm: disbuf, 861 ReqSigs: int32(reqSigs), 862 Type: scriptClass.String(), 863 Addresses: addresses, 864 } 865 if scriptClass != txscript.ScriptHashTy { 866 reply.P2sh = p2sh.EncodeAddress() 867 } 868 869 // Address is defined when there's a single well-defined 870 // receiver address. To spend the output a signature for this, 871 // and only this, address is required. 872 if len(addresses) == 1 && reqSigs <= 1 { 873 reply.Address = addresses[0] 874 } 875 return reply, nil 876 } 877 878 // handleEstimateFee handles estimatefee commands. 879 func handleEstimateFee(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 880 c := cmd.(*btcjson.EstimateFeeCmd) 881 882 if s.cfg.FeeEstimator == nil { 883 return nil, errors.New("Fee estimation disabled") 884 } 885 886 if c.NumBlocks <= 0 { 887 return -1.0, errors.New("Parameter NumBlocks must be positive") 888 } 889 890 feeRate, err := s.cfg.FeeEstimator.EstimateFee(uint32(c.NumBlocks)) 891 892 if err != nil { 893 return -1.0, err 894 } 895 896 // Convert to satoshis per kb. 897 return float64(feeRate), nil 898 } 899 900 // handleGenerate handles generate commands. 901 func handleGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 902 // Respond with an error if there are no addresses to pay the 903 // created blocks to. 904 if len(cfg.miningAddrs) == 0 { 905 return nil, &btcjson.RPCError{ 906 Code: btcjson.ErrRPCInternal.Code, 907 Message: "No payment addresses specified " + 908 "via --miningaddr", 909 } 910 } 911 912 // Respond with an error if there's virtually 0 chance of mining a block 913 // with the CPU. 914 if !s.cfg.ChainParams.GenerateSupported { 915 return nil, &btcjson.RPCError{ 916 Code: btcjson.ErrRPCDifficulty, 917 Message: fmt.Sprintf("No support for `generate` on "+ 918 "the current network, %s, as it's unlikely to "+ 919 "be possible to mine a block with the CPU.", 920 s.cfg.ChainParams.Net), 921 } 922 } 923 924 c := cmd.(*btcjson.GenerateCmd) 925 926 // Respond with an error if the client is requesting 0 blocks to be generated. 927 if c.NumBlocks == 0 { 928 return nil, &btcjson.RPCError{ 929 Code: btcjson.ErrRPCInternal.Code, 930 Message: "Please request a nonzero number of blocks to generate.", 931 } 932 } 933 934 // Create a reply 935 reply := make([]string, c.NumBlocks) 936 937 blockHashes, err := s.cfg.CPUMiner.GenerateNBlocks(c.NumBlocks) 938 if err != nil { 939 return nil, &btcjson.RPCError{ 940 Code: btcjson.ErrRPCInternal.Code, 941 Message: err.Error(), 942 } 943 } 944 945 // Mine the correct number of blocks, assigning the hex representation of the 946 // hash of each one to its place in the reply. 947 for i, hash := range blockHashes { 948 reply[i] = hash.String() 949 } 950 951 return reply, nil 952 } 953 954 // handleGetAddedNodeInfo handles getaddednodeinfo commands. 955 func handleGetAddedNodeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 956 c := cmd.(*btcjson.GetAddedNodeInfoCmd) 957 958 // Retrieve a list of persistent (added) peers from the server and 959 // filter the list of peers per the specified address (if any). 960 peers := s.cfg.ConnMgr.PersistentPeers() 961 if c.Node != nil { 962 node := *c.Node 963 found := false 964 for i, peer := range peers { 965 if peer.ToPeer().Addr() == node { 966 peers = peers[i : i+1] 967 found = true 968 } 969 } 970 if !found { 971 return nil, &btcjson.RPCError{ 972 Code: btcjson.ErrRPCClientNodeNotAdded, 973 Message: "Node has not been added", 974 } 975 } 976 } 977 978 // Without the dns flag, the result is just a slice of the addresses as 979 // strings. 980 if !c.DNS { 981 results := make([]string, 0, len(peers)) 982 for _, peer := range peers { 983 results = append(results, peer.ToPeer().Addr()) 984 } 985 return results, nil 986 } 987 988 // With the dns flag, the result is an array of JSON objects which 989 // include the result of DNS lookups for each peer. 990 results := make([]*btcjson.GetAddedNodeInfoResult, 0, len(peers)) 991 for _, rpcPeer := range peers { 992 // Set the "address" of the peer which could be an ip address 993 // or a domain name. 994 peer := rpcPeer.ToPeer() 995 var result btcjson.GetAddedNodeInfoResult 996 result.AddedNode = peer.Addr() 997 result.Connected = btcjson.Bool(peer.Connected()) 998 999 // Split the address into host and port portions so we can do 1000 // a DNS lookup against the host. When no port is specified in 1001 // the address, just use the address as the host. 1002 host, _, err := net.SplitHostPort(peer.Addr()) 1003 if err != nil { 1004 host = peer.Addr() 1005 } 1006 1007 var ipList []string 1008 switch { 1009 case net.ParseIP(host) != nil, strings.HasSuffix(host, ".onion"): 1010 ipList = make([]string, 1) 1011 ipList[0] = host 1012 default: 1013 // Do a DNS lookup for the address. If the lookup fails, just 1014 // use the host. 1015 ips, err := btcdLookup(host) 1016 if err != nil { 1017 ipList = make([]string, 1) 1018 ipList[0] = host 1019 break 1020 } 1021 ipList = make([]string, 0, len(ips)) 1022 for _, ip := range ips { 1023 ipList = append(ipList, ip.String()) 1024 } 1025 } 1026 1027 // Add the addresses and connection info to the result. 1028 addrs := make([]btcjson.GetAddedNodeInfoResultAddr, 0, len(ipList)) 1029 for _, ip := range ipList { 1030 var addr btcjson.GetAddedNodeInfoResultAddr 1031 addr.Address = ip 1032 addr.Connected = "false" 1033 if ip == host && peer.Connected() { 1034 addr.Connected = directionString(peer.Inbound()) 1035 } 1036 addrs = append(addrs, addr) 1037 } 1038 result.Addresses = &addrs 1039 results = append(results, &result) 1040 } 1041 return results, nil 1042 } 1043 1044 // handleGetBestBlock implements the getbestblock command. 1045 func handleGetBestBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 1046 // All other "get block" commands give either the height, the 1047 // hash, or both but require the block SHA. This gets both for 1048 // the best block. 1049 best := s.cfg.Chain.BestSnapshot() 1050 result := &btcjson.GetBestBlockResult{ 1051 Hash: best.Hash.String(), 1052 Height: best.Height, 1053 } 1054 return result, nil 1055 } 1056 1057 // handleGetBestBlockHash implements the getbestblockhash command. 1058 func handleGetBestBlockHash(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 1059 best := s.cfg.Chain.BestSnapshot() 1060 return best.Hash.String(), nil 1061 } 1062 1063 // getDifficultyRatio returns the proof-of-work difficulty as a multiple of the 1064 // minimum difficulty using the passed bits field from the header of a block. 1065 func getDifficultyRatio(bits uint32, params *chaincfg.Params) float64 { 1066 // The minimum difficulty is the max possible proof-of-work limit bits 1067 // converted back to a number. Note this is not the same as the proof of 1068 // work limit directly because the block difficulty is encoded in a block 1069 // with the compact form which loses precision. 1070 max := blockchain.CompactToBig(params.PowLimitBits) 1071 target := blockchain.CompactToBig(bits) 1072 1073 difficulty := new(big.Rat).SetFrac(max, target) 1074 outString := difficulty.FloatString(8) 1075 diff, err := strconv.ParseFloat(outString, 64) 1076 if err != nil { 1077 rpcsLog.Errorf("Cannot get difficulty: %v", err) 1078 return 0 1079 } 1080 return diff 1081 } 1082 1083 // handleGetBlock implements the getblock command. 1084 func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 1085 c := cmd.(*btcjson.GetBlockCmd) 1086 1087 // Load the raw block bytes from the database. 1088 hash, err := chainhash.NewHashFromStr(c.Hash) 1089 if err != nil { 1090 return nil, rpcDecodeHexError(c.Hash) 1091 } 1092 var blkBytes []byte 1093 err = s.cfg.DB.View(func(dbTx database.Tx) error { 1094 var err error 1095 blkBytes, err = dbTx.FetchBlock(hash) 1096 return err 1097 }) 1098 if err != nil { 1099 return nil, &btcjson.RPCError{ 1100 Code: btcjson.ErrRPCBlockNotFound, 1101 Message: "Block not found", 1102 } 1103 } 1104 // If verbosity is 0, return the serialized block as a hex encoded string. 1105 if c.Verbosity != nil && *c.Verbosity == 0 { 1106 return hex.EncodeToString(blkBytes), nil 1107 } 1108 1109 // Otherwise, generate the JSON object and return it. 1110 1111 // Deserialize the block. 1112 blk, err := btcutil.NewBlockFromBytes(blkBytes) 1113 if err != nil { 1114 context := "Failed to deserialize block" 1115 return nil, internalRPCError(err.Error(), context) 1116 } 1117 1118 // Get the block height from chain. 1119 blockHeight, err := s.cfg.Chain.BlockHeightByHash(hash) 1120 if err != nil { 1121 context := "Failed to obtain block height" 1122 return nil, internalRPCError(err.Error(), context) 1123 } 1124 blk.SetHeight(blockHeight) 1125 best := s.cfg.Chain.BestSnapshot() 1126 1127 // Get next block hash unless there are none. 1128 var nextHashString string 1129 if blockHeight < best.Height { 1130 nextHash, err := s.cfg.Chain.BlockHashByHeight(blockHeight + 1) 1131 if err != nil { 1132 context := "No next block" 1133 return nil, internalRPCError(err.Error(), context) 1134 } 1135 nextHashString = nextHash.String() 1136 } 1137 1138 params := s.cfg.ChainParams 1139 blockHeader := &blk.MsgBlock().Header 1140 blockReply := btcjson.GetBlockVerboseResult{ 1141 Hash: c.Hash, 1142 Version: blockHeader.Version, 1143 VersionHex: fmt.Sprintf("%08x", blockHeader.Version), 1144 MerkleRoot: blockHeader.MerkleRoot.String(), 1145 PreviousHash: blockHeader.PrevBlock.String(), 1146 Nonce: blockHeader.Nonce, 1147 Time: blockHeader.Timestamp.Unix(), 1148 Confirmations: int64(1 + best.Height - blockHeight), 1149 Height: int64(blockHeight), 1150 Size: int32(len(blkBytes)), 1151 StrippedSize: int32(blk.MsgBlock().SerializeSizeStripped()), 1152 Weight: int32(blockchain.GetBlockWeight(blk)), 1153 Bits: strconv.FormatInt(int64(blockHeader.Bits), 16), 1154 Difficulty: getDifficultyRatio(blockHeader.Bits, params), 1155 NextHash: nextHashString, 1156 } 1157 1158 if *c.Verbosity == 1 { 1159 transactions := blk.Transactions() 1160 txNames := make([]string, len(transactions)) 1161 for i, tx := range transactions { 1162 txNames[i] = tx.Hash().String() 1163 } 1164 1165 blockReply.Tx = txNames 1166 } else { 1167 txns := blk.Transactions() 1168 rawTxns := make([]btcjson.TxRawResult, len(txns)) 1169 for i, tx := range txns { 1170 rawTxn, err := createTxRawResult(params, tx.MsgTx(), 1171 tx.Hash().String(), blockHeader, hash.String(), 1172 blockHeight, best.Height) 1173 if err != nil { 1174 return nil, err 1175 } 1176 rawTxns[i] = *rawTxn 1177 } 1178 blockReply.RawTx = rawTxns 1179 } 1180 1181 return blockReply, nil 1182 } 1183 1184 // softForkStatus converts a ThresholdState state into a human readable string 1185 // corresponding to the particular state. 1186 func softForkStatus(state blockchain.ThresholdState) (string, error) { 1187 switch state { 1188 case blockchain.ThresholdDefined: 1189 return "defined", nil 1190 case blockchain.ThresholdStarted: 1191 return "started", nil 1192 case blockchain.ThresholdLockedIn: 1193 return "lockedin", nil 1194 case blockchain.ThresholdActive: 1195 return "active", nil 1196 case blockchain.ThresholdFailed: 1197 return "failed", nil 1198 default: 1199 return "", fmt.Errorf("unknown deployment state: %v", state) 1200 } 1201 } 1202 1203 // handleGetBlockChainInfo implements the getblockchaininfo command. 1204 func handleGetBlockChainInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 1205 // Obtain a snapshot of the current best known blockchain state. We'll 1206 // populate the response to this call primarily from this snapshot. 1207 params := s.cfg.ChainParams 1208 chain := s.cfg.Chain 1209 chainSnapshot := chain.BestSnapshot() 1210 1211 chainInfo := &btcjson.GetBlockChainInfoResult{ 1212 Chain: params.Name, 1213 Blocks: chainSnapshot.Height, 1214 Headers: chainSnapshot.Height, 1215 BestBlockHash: chainSnapshot.Hash.String(), 1216 Difficulty: getDifficultyRatio(chainSnapshot.Bits, params), 1217 MedianTime: chainSnapshot.MedianTime.Unix(), 1218 Pruned: cfg.Prune != 0, 1219 SoftForks: &btcjson.SoftForks{ 1220 Bip9SoftForks: make(map[string]*btcjson.Bip9SoftForkDescription), 1221 }, 1222 } 1223 1224 // Next, populate the response with information describing the current 1225 // status of soft-forks deployed via the super-majority block 1226 // signalling mechanism. 1227 height := chainSnapshot.Height 1228 chainInfo.SoftForks.SoftForks = []*btcjson.SoftForkDescription{ 1229 { 1230 ID: "bip34", 1231 Version: 2, 1232 Reject: struct { 1233 Status bool `json:"status"` 1234 }{ 1235 Status: height >= params.BIP0034Height, 1236 }, 1237 }, 1238 { 1239 ID: "bip66", 1240 Version: 3, 1241 Reject: struct { 1242 Status bool `json:"status"` 1243 }{ 1244 Status: height >= params.BIP0066Height, 1245 }, 1246 }, 1247 { 1248 ID: "bip65", 1249 Version: 4, 1250 Reject: struct { 1251 Status bool `json:"status"` 1252 }{ 1253 Status: height >= params.BIP0065Height, 1254 }, 1255 }, 1256 } 1257 1258 // Finally, query the BIP0009 version bits state for all currently 1259 // defined BIP0009 soft-fork deployments. 1260 for deployment, deploymentDetails := range params.Deployments { 1261 // Map the integer deployment ID into a human readable 1262 // fork-name. 1263 var forkName string 1264 switch deployment { 1265 case chaincfg.DeploymentTestDummy: 1266 forkName = "dummy" 1267 1268 case chaincfg.DeploymentTestDummyMinActivation: 1269 forkName = "dummy-min-activation" 1270 1271 case chaincfg.DeploymentCSV: 1272 forkName = "csv" 1273 1274 case chaincfg.DeploymentSegwit: 1275 forkName = "segwit" 1276 1277 case chaincfg.DeploymentTaproot: 1278 forkName = "taproot" 1279 1280 default: 1281 return nil, &btcjson.RPCError{ 1282 Code: btcjson.ErrRPCInternal.Code, 1283 Message: fmt.Sprintf("Unknown deployment %v "+ 1284 "detected", deployment), 1285 } 1286 } 1287 1288 // Query the chain for the current status of the deployment as 1289 // identified by its deployment ID. 1290 deploymentStatus, err := chain.ThresholdState(uint32(deployment)) 1291 if err != nil { 1292 context := "Failed to obtain deployment status" 1293 return nil, internalRPCError(err.Error(), context) 1294 } 1295 1296 // Attempt to convert the current deployment status into a 1297 // human readable string. If the status is unrecognized, then a 1298 // non-nil error is returned. 1299 statusString, err := softForkStatus(deploymentStatus) 1300 if err != nil { 1301 return nil, &btcjson.RPCError{ 1302 Code: btcjson.ErrRPCInternal.Code, 1303 Message: fmt.Sprintf("unknown deployment status: %v", 1304 deploymentStatus), 1305 } 1306 } 1307 1308 // Finally, populate the soft-fork description with all the 1309 // information gathered above. 1310 var startTime, endTime int64 1311 if starter, ok := deploymentDetails.DeploymentStarter.(*chaincfg.MedianTimeDeploymentStarter); ok { 1312 startTime = starter.StartTime().Unix() 1313 } 1314 if ender, ok := deploymentDetails.DeploymentEnder.(*chaincfg.MedianTimeDeploymentEnder); ok { 1315 endTime = ender.EndTime().Unix() 1316 } 1317 chainInfo.SoftForks.Bip9SoftForks[forkName] = &btcjson.Bip9SoftForkDescription{ 1318 Status: strings.ToLower(statusString), 1319 Bit: deploymentDetails.BitNumber, 1320 StartTime2: startTime, 1321 Timeout: endTime, 1322 MinActivationHeight: int32(deploymentDetails.MinActivationHeight), 1323 } 1324 } 1325 1326 return chainInfo, nil 1327 } 1328 1329 // handleGetBlockCount implements the getblockcount command. 1330 func handleGetBlockCount(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 1331 best := s.cfg.Chain.BestSnapshot() 1332 return int64(best.Height), nil 1333 } 1334 1335 // handleGetBlockHash implements the getblockhash command. 1336 func handleGetBlockHash(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 1337 c := cmd.(*btcjson.GetBlockHashCmd) 1338 hash, err := s.cfg.Chain.BlockHashByHeight(int32(c.Index)) 1339 if err != nil { 1340 return nil, &btcjson.RPCError{ 1341 Code: btcjson.ErrRPCOutOfRange, 1342 Message: "Block number out of range", 1343 } 1344 } 1345 1346 return hash.String(), nil 1347 } 1348 1349 // handleGetBlockHeader implements the getblockheader command. 1350 func handleGetBlockHeader(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 1351 c := cmd.(*btcjson.GetBlockHeaderCmd) 1352 1353 // Fetch the header from chain. 1354 hash, err := chainhash.NewHashFromStr(c.Hash) 1355 if err != nil { 1356 return nil, rpcDecodeHexError(c.Hash) 1357 } 1358 blockHeader, err := s.cfg.Chain.HeaderByHash(hash) 1359 if err != nil { 1360 return nil, &btcjson.RPCError{ 1361 Code: btcjson.ErrRPCBlockNotFound, 1362 Message: "Block not found", 1363 } 1364 } 1365 1366 // When the verbose flag isn't set, simply return the serialized block 1367 // header as a hex-encoded string. 1368 if c.Verbose != nil && !*c.Verbose { 1369 var headerBuf bytes.Buffer 1370 err := blockHeader.Serialize(&headerBuf) 1371 if err != nil { 1372 context := "Failed to serialize block header" 1373 return nil, internalRPCError(err.Error(), context) 1374 } 1375 return hex.EncodeToString(headerBuf.Bytes()), nil 1376 } 1377 1378 // The verbose flag is set, so generate the JSON object and return it. 1379 1380 // Get the block height from chain. 1381 blockHeight, err := s.cfg.Chain.BlockHeightByHash(hash) 1382 if err != nil { 1383 context := "Failed to obtain block height" 1384 return nil, internalRPCError(err.Error(), context) 1385 } 1386 best := s.cfg.Chain.BestSnapshot() 1387 1388 // Get next block hash unless there are none. 1389 var nextHashString string 1390 if blockHeight < best.Height { 1391 nextHash, err := s.cfg.Chain.BlockHashByHeight(blockHeight + 1) 1392 if err != nil { 1393 context := "No next block" 1394 return nil, internalRPCError(err.Error(), context) 1395 } 1396 nextHashString = nextHash.String() 1397 } 1398 1399 params := s.cfg.ChainParams 1400 blockHeaderReply := btcjson.GetBlockHeaderVerboseResult{ 1401 Hash: c.Hash, 1402 Confirmations: int64(1 + best.Height - blockHeight), 1403 Height: blockHeight, 1404 Version: blockHeader.Version, 1405 VersionHex: fmt.Sprintf("%08x", blockHeader.Version), 1406 MerkleRoot: blockHeader.MerkleRoot.String(), 1407 NextHash: nextHashString, 1408 PreviousHash: blockHeader.PrevBlock.String(), 1409 Nonce: uint64(blockHeader.Nonce), 1410 Time: blockHeader.Timestamp.Unix(), 1411 Bits: strconv.FormatInt(int64(blockHeader.Bits), 16), 1412 Difficulty: getDifficultyRatio(blockHeader.Bits, params), 1413 } 1414 return blockHeaderReply, nil 1415 } 1416 1417 // encodeTemplateID encodes the passed details into an ID that can be used to 1418 // uniquely identify a block template. 1419 func encodeTemplateID(prevHash *chainhash.Hash, lastGenerated time.Time) string { 1420 return fmt.Sprintf("%s-%d", prevHash.String(), lastGenerated.Unix()) 1421 } 1422 1423 // decodeTemplateID decodes an ID that is used to uniquely identify a block 1424 // template. This is mainly used as a mechanism to track when to update clients 1425 // that are using long polling for block templates. The ID consists of the 1426 // previous block hash for the associated template and the time the associated 1427 // template was generated. 1428 func decodeTemplateID(templateID string) (*chainhash.Hash, int64, error) { 1429 fields := strings.Split(templateID, "-") 1430 if len(fields) != 2 { 1431 return nil, 0, errors.New("invalid longpollid format") 1432 } 1433 1434 prevHash, err := chainhash.NewHashFromStr(fields[0]) 1435 if err != nil { 1436 return nil, 0, errors.New("invalid longpollid format") 1437 } 1438 lastGenerated, err := strconv.ParseInt(fields[1], 10, 64) 1439 if err != nil { 1440 return nil, 0, errors.New("invalid longpollid format") 1441 } 1442 1443 return prevHash, lastGenerated, nil 1444 } 1445 1446 // notifyLongPollers notifies any channels that have been registered to be 1447 // notified when block templates are stale. 1448 // 1449 // This function MUST be called with the state locked. 1450 func (state *gbtWorkState) notifyLongPollers(latestHash *chainhash.Hash, lastGenerated time.Time) { 1451 // Notify anything that is waiting for a block template update from a 1452 // hash which is not the hash of the tip of the best chain since their 1453 // work is now invalid. 1454 for hash, channels := range state.notifyMap { 1455 if !hash.IsEqual(latestHash) { 1456 for _, c := range channels { 1457 close(c) 1458 } 1459 delete(state.notifyMap, hash) 1460 } 1461 } 1462 1463 // Return now if the provided last generated timestamp has not been 1464 // initialized. 1465 if lastGenerated.IsZero() { 1466 return 1467 } 1468 1469 // Return now if there is nothing registered for updates to the current 1470 // best block hash. 1471 channels, ok := state.notifyMap[*latestHash] 1472 if !ok { 1473 return 1474 } 1475 1476 // Notify anything that is waiting for a block template update from a 1477 // block template generated before the most recently generated block 1478 // template. 1479 lastGeneratedUnix := lastGenerated.Unix() 1480 for lastGen, c := range channels { 1481 if lastGen < lastGeneratedUnix { 1482 close(c) 1483 delete(channels, lastGen) 1484 } 1485 } 1486 1487 // Remove the entry altogether if there are no more registered 1488 // channels. 1489 if len(channels) == 0 { 1490 delete(state.notifyMap, *latestHash) 1491 } 1492 } 1493 1494 // NotifyBlockConnected uses the newly-connected block to notify any long poll 1495 // clients with a new block template when their existing block template is 1496 // stale due to the newly connected block. 1497 func (state *gbtWorkState) NotifyBlockConnected(blockHash *chainhash.Hash) { 1498 go func() { 1499 state.Lock() 1500 defer state.Unlock() 1501 1502 state.notifyLongPollers(blockHash, state.lastTxUpdate) 1503 }() 1504 } 1505 1506 // NotifyMempoolTx uses the new last updated time for the transaction memory 1507 // pool to notify any long poll clients with a new block template when their 1508 // existing block template is stale due to enough time passing and the contents 1509 // of the memory pool changing. 1510 func (state *gbtWorkState) NotifyMempoolTx(lastUpdated time.Time) { 1511 go func() { 1512 state.Lock() 1513 defer state.Unlock() 1514 1515 // No need to notify anything if no block templates have been generated 1516 // yet. 1517 if state.prevHash == nil || state.lastGenerated.IsZero() { 1518 return 1519 } 1520 1521 if time.Now().After(state.lastGenerated.Add(time.Second * 1522 gbtRegenerateSeconds)) { 1523 1524 state.notifyLongPollers(state.prevHash, lastUpdated) 1525 } 1526 }() 1527 } 1528 1529 // templateUpdateChan returns a channel that will be closed once the block 1530 // template associated with the passed previous hash and last generated time 1531 // is stale. The function will return existing channels for duplicate 1532 // parameters which allows multiple clients to wait for the same block template 1533 // without requiring a different channel for each client. 1534 // 1535 // This function MUST be called with the state locked. 1536 func (state *gbtWorkState) templateUpdateChan(prevHash *chainhash.Hash, lastGenerated int64) chan struct{} { 1537 // Either get the current list of channels waiting for updates about 1538 // changes to block template for the previous hash or create a new one. 1539 channels, ok := state.notifyMap[*prevHash] 1540 if !ok { 1541 m := make(map[int64]chan struct{}) 1542 state.notifyMap[*prevHash] = m 1543 channels = m 1544 } 1545 1546 // Get the current channel associated with the time the block template 1547 // was last generated or create a new one. 1548 c, ok := channels[lastGenerated] 1549 if !ok { 1550 c = make(chan struct{}) 1551 channels[lastGenerated] = c 1552 } 1553 1554 return c 1555 } 1556 1557 // updateBlockTemplate creates or updates a block template for the work state. 1558 // A new block template will be generated when the current best block has 1559 // changed or the transactions in the memory pool have been updated and it has 1560 // been long enough since the last template was generated. Otherwise, the 1561 // timestamp for the existing block template is updated (and possibly the 1562 // difficulty on testnet per the consesus rules). Finally, if the 1563 // useCoinbaseValue flag is false and the existing block template does not 1564 // already contain a valid payment address, the block template will be updated 1565 // with a randomly selected payment address from the list of configured 1566 // addresses. 1567 // 1568 // This function MUST be called with the state locked. 1569 func (state *gbtWorkState) updateBlockTemplate(s *rpcServer, useCoinbaseValue bool) error { 1570 generator := s.cfg.Generator 1571 lastTxUpdate := generator.TxSource().LastUpdated() 1572 if lastTxUpdate.IsZero() { 1573 lastTxUpdate = time.Now() 1574 } 1575 1576 // Generate a new block template when the current best block has 1577 // changed or the transactions in the memory pool have been updated and 1578 // it has been at least gbtRegenerateSecond since the last template was 1579 // generated. 1580 var msgBlock *wire.MsgBlock 1581 var targetDifficulty string 1582 latestHash := &s.cfg.Chain.BestSnapshot().Hash 1583 template := state.template 1584 if template == nil || state.prevHash == nil || 1585 !state.prevHash.IsEqual(latestHash) || 1586 (state.lastTxUpdate != lastTxUpdate && 1587 time.Now().After(state.lastGenerated.Add(time.Second* 1588 gbtRegenerateSeconds))) { 1589 1590 // Reset the previous best hash the block template was generated 1591 // against so any errors below cause the next invocation to try 1592 // again. 1593 state.prevHash = nil 1594 1595 // Choose a payment address at random if the caller requests a 1596 // full coinbase as opposed to only the pertinent details needed 1597 // to create their own coinbase. 1598 var payAddr btcutil.Address 1599 if !useCoinbaseValue { 1600 payAddr = cfg.miningAddrs[rand.Intn(len(cfg.miningAddrs))] 1601 } 1602 1603 // Create a new block template that has a coinbase which anyone 1604 // can redeem. This is only acceptable because the returned 1605 // block template doesn't include the coinbase, so the caller 1606 // will ultimately create their own coinbase which pays to the 1607 // appropriate address(es). 1608 blkTemplate, err := generator.NewBlockTemplate(payAddr) 1609 if err != nil { 1610 return internalRPCError("Failed to create new block "+ 1611 "template: "+err.Error(), "") 1612 } 1613 template = blkTemplate 1614 msgBlock = template.Block 1615 targetDifficulty = fmt.Sprintf("%064x", 1616 blockchain.CompactToBig(msgBlock.Header.Bits)) 1617 1618 // Get the minimum allowed timestamp for the block based on the 1619 // median timestamp of the last several blocks per the chain 1620 // consensus rules. 1621 best := s.cfg.Chain.BestSnapshot() 1622 minTimestamp := mining.MinimumMedianTime(best) 1623 1624 // Update work state to ensure another block template isn't 1625 // generated until needed. 1626 state.template = template 1627 state.lastGenerated = time.Now() 1628 state.lastTxUpdate = lastTxUpdate 1629 state.prevHash = latestHash 1630 state.minTimestamp = minTimestamp 1631 1632 rpcsLog.Debugf("Generated block template (timestamp %v, "+ 1633 "target %s, merkle root %s)", 1634 msgBlock.Header.Timestamp, targetDifficulty, 1635 msgBlock.Header.MerkleRoot) 1636 1637 // Notify any clients that are long polling about the new 1638 // template. 1639 state.notifyLongPollers(latestHash, lastTxUpdate) 1640 } else { 1641 // At this point, there is a saved block template and another 1642 // request for a template was made, but either the available 1643 // transactions haven't change or it hasn't been long enough to 1644 // trigger a new block template to be generated. So, update the 1645 // existing block template. 1646 1647 // When the caller requires a full coinbase as opposed to only 1648 // the pertinent details needed to create their own coinbase, 1649 // add a payment address to the output of the coinbase of the 1650 // template if it doesn't already have one. Since this requires 1651 // mining addresses to be specified via the config, an error is 1652 // returned if none have been specified. 1653 if !useCoinbaseValue && !template.ValidPayAddress { 1654 // Choose a payment address at random. 1655 payToAddr := cfg.miningAddrs[rand.Intn(len(cfg.miningAddrs))] 1656 1657 // Update the block coinbase output of the template to 1658 // pay to the randomly selected payment address. 1659 pkScript, err := txscript.PayToAddrScript(payToAddr) 1660 if err != nil { 1661 context := "Failed to create pay-to-addr script" 1662 return internalRPCError(err.Error(), context) 1663 } 1664 template.Block.Transactions[0].TxOut[0].PkScript = pkScript 1665 template.ValidPayAddress = true 1666 1667 // Update the merkle root. 1668 block := btcutil.NewBlock(template.Block) 1669 merkleRoot := blockchain.CalcMerkleRoot(block.Transactions(), false) 1670 template.Block.Header.MerkleRoot = merkleRoot 1671 } 1672 1673 // Set locals for convenience. 1674 msgBlock = template.Block 1675 targetDifficulty = fmt.Sprintf("%064x", 1676 blockchain.CompactToBig(msgBlock.Header.Bits)) 1677 1678 // Update the time of the block template to the current time 1679 // while accounting for the median time of the past several 1680 // blocks per the chain consensus rules. 1681 generator.UpdateBlockTime(msgBlock) 1682 msgBlock.Header.Nonce = 0 1683 1684 rpcsLog.Debugf("Updated block template (timestamp %v, "+ 1685 "target %s)", msgBlock.Header.Timestamp, 1686 targetDifficulty) 1687 } 1688 1689 return nil 1690 } 1691 1692 // blockTemplateResult returns the current block template associated with the 1693 // state as a btcjson.GetBlockTemplateResult that is ready to be encoded to JSON 1694 // and returned to the caller. 1695 // 1696 // This function MUST be called with the state locked. 1697 func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld *bool) (*btcjson.GetBlockTemplateResult, error) { 1698 // Ensure the timestamps are still in valid range for the template. 1699 // This should really only ever happen if the local clock is changed 1700 // after the template is generated, but it's important to avoid serving 1701 // invalid block templates. 1702 template := state.template 1703 msgBlock := template.Block 1704 header := &msgBlock.Header 1705 adjustedTime := state.timeSource.AdjustedTime() 1706 maxTime := adjustedTime.Add(time.Second * blockchain.MaxTimeOffsetSeconds) 1707 if header.Timestamp.After(maxTime) { 1708 return nil, &btcjson.RPCError{ 1709 Code: btcjson.ErrRPCOutOfRange, 1710 Message: fmt.Sprintf("The template time is after the "+ 1711 "maximum allowed time for a block - template "+ 1712 "time %v, maximum time %v", adjustedTime, 1713 maxTime), 1714 } 1715 } 1716 1717 // Convert each transaction in the block template to a template result 1718 // transaction. The result does not include the coinbase, so notice 1719 // the adjustments to the various lengths and indices. 1720 numTx := len(msgBlock.Transactions) 1721 transactions := make([]btcjson.GetBlockTemplateResultTx, 0, numTx-1) 1722 txIndex := make(map[chainhash.Hash]int64, numTx) 1723 for i, tx := range msgBlock.Transactions { 1724 txID := tx.TxHash() 1725 txIndex[txID] = int64(i) 1726 1727 // Skip the coinbase transaction. 1728 if i == 0 { 1729 continue 1730 } 1731 1732 // Create an array of 1-based indices to transactions that come 1733 // before this one in the transactions list which this one 1734 // depends on. This is necessary since the created block must 1735 // ensure proper ordering of the dependencies. A map is used 1736 // before creating the final array to prevent duplicate entries 1737 // when multiple inputs reference the same transaction. 1738 dependsMap := make(map[int64]struct{}) 1739 for _, txIn := range tx.TxIn { 1740 if idx, ok := txIndex[txIn.PreviousOutPoint.Hash]; ok { 1741 dependsMap[idx] = struct{}{} 1742 } 1743 } 1744 depends := make([]int64, 0, len(dependsMap)) 1745 for idx := range dependsMap { 1746 depends = append(depends, idx) 1747 } 1748 1749 // Serialize the transaction for later conversion to hex. 1750 txBuf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize())) 1751 if err := tx.Serialize(txBuf); err != nil { 1752 context := "Failed to serialize transaction" 1753 return nil, internalRPCError(err.Error(), context) 1754 } 1755 1756 bTx := btcutil.NewTx(tx) 1757 resultTx := btcjson.GetBlockTemplateResultTx{ 1758 Data: hex.EncodeToString(txBuf.Bytes()), 1759 TxID: txID.String(), 1760 Hash: tx.WitnessHash().String(), 1761 Depends: depends, 1762 Fee: template.Fees[i], 1763 SigOps: template.SigOpCosts[i], 1764 Weight: blockchain.GetTransactionWeight(bTx), 1765 } 1766 transactions = append(transactions, resultTx) 1767 } 1768 1769 // Generate the block template reply. Note that following mutations are 1770 // implied by the included or omission of fields: 1771 // Including MinTime -> time/decrement 1772 // Omitting CoinbaseTxn -> coinbase, generation 1773 targetDifficulty := fmt.Sprintf("%064x", blockchain.CompactToBig(header.Bits)) 1774 templateID := encodeTemplateID(state.prevHash, state.lastGenerated) 1775 reply := btcjson.GetBlockTemplateResult{ 1776 Bits: strconv.FormatInt(int64(header.Bits), 16), 1777 CurTime: header.Timestamp.Unix(), 1778 Height: int64(template.Height), 1779 PreviousHash: header.PrevBlock.String(), 1780 WeightLimit: blockchain.MaxBlockWeight, 1781 SigOpLimit: blockchain.MaxBlockSigOpsCost, 1782 SizeLimit: wire.MaxBlockPayload, 1783 Transactions: transactions, 1784 Version: header.Version, 1785 LongPollID: templateID, 1786 SubmitOld: submitOld, 1787 Target: targetDifficulty, 1788 MinTime: state.minTimestamp.Unix(), 1789 MaxTime: maxTime.Unix(), 1790 Mutable: gbtMutableFields, 1791 NonceRange: gbtNonceRange, 1792 Capabilities: gbtCapabilities, 1793 } 1794 // If the generated block template includes transactions with witness 1795 // data, then include the witness commitment in the GBT result. 1796 if template.WitnessCommitment != nil { 1797 reply.DefaultWitnessCommitment = hex.EncodeToString(template.WitnessCommitment) 1798 } 1799 1800 if useCoinbaseValue { 1801 reply.CoinbaseAux = gbtCoinbaseAux 1802 reply.CoinbaseValue = &msgBlock.Transactions[0].TxOut[0].Value 1803 } else { 1804 // Ensure the template has a valid payment address associated 1805 // with it when a full coinbase is requested. 1806 if !template.ValidPayAddress { 1807 return nil, &btcjson.RPCError{ 1808 Code: btcjson.ErrRPCInternal.Code, 1809 Message: "A coinbase transaction has been " + 1810 "requested, but the server has not " + 1811 "been configured with any payment " + 1812 "addresses via --miningaddr", 1813 } 1814 } 1815 1816 // Serialize the transaction for conversion to hex. 1817 tx := msgBlock.Transactions[0] 1818 txBuf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize())) 1819 if err := tx.Serialize(txBuf); err != nil { 1820 context := "Failed to serialize transaction" 1821 return nil, internalRPCError(err.Error(), context) 1822 } 1823 1824 resultTx := btcjson.GetBlockTemplateResultTx{ 1825 Data: hex.EncodeToString(txBuf.Bytes()), 1826 Hash: tx.TxHash().String(), 1827 Depends: []int64{}, 1828 Fee: template.Fees[0], 1829 SigOps: template.SigOpCosts[0], 1830 } 1831 1832 reply.CoinbaseTxn = &resultTx 1833 } 1834 1835 return &reply, nil 1836 } 1837 1838 // handleGetBlockTemplateLongPoll is a helper for handleGetBlockTemplateRequest 1839 // which deals with handling long polling for block templates. When a caller 1840 // sends a request with a long poll ID that was previously returned, a response 1841 // is not sent until the caller should stop working on the previous block 1842 // template in favor of the new one. In particular, this is the case when the 1843 // old block template is no longer valid due to a solution already being found 1844 // and added to the block chain, or new transactions have shown up and some time 1845 // has passed without finding a solution. 1846 // 1847 // See https://en.bitcoin.it/wiki/BIP_0022 for more details. 1848 func handleGetBlockTemplateLongPoll(s *rpcServer, longPollID string, useCoinbaseValue bool, closeChan <-chan struct{}) (interface{}, error) { 1849 state := s.gbtWorkState 1850 state.Lock() 1851 // The state unlock is intentionally not deferred here since it needs to 1852 // be manually unlocked before waiting for a notification about block 1853 // template changes. 1854 1855 if err := state.updateBlockTemplate(s, useCoinbaseValue); err != nil { 1856 state.Unlock() 1857 return nil, err 1858 } 1859 1860 // Just return the current block template if the long poll ID provided by 1861 // the caller is invalid. 1862 prevHash, lastGenerated, err := decodeTemplateID(longPollID) 1863 if err != nil { 1864 result, err := state.blockTemplateResult(useCoinbaseValue, nil) 1865 if err != nil { 1866 state.Unlock() 1867 return nil, err 1868 } 1869 1870 state.Unlock() 1871 return result, nil 1872 } 1873 1874 // Return the block template now if the specific block template 1875 // identified by the long poll ID no longer matches the current block 1876 // template as this means the provided template is stale. 1877 prevTemplateHash := &state.template.Block.Header.PrevBlock 1878 if !prevHash.IsEqual(prevTemplateHash) || 1879 lastGenerated != state.lastGenerated.Unix() { 1880 1881 // Include whether or not it is valid to submit work against the 1882 // old block template depending on whether or not a solution has 1883 // already been found and added to the block chain. 1884 submitOld := prevHash.IsEqual(prevTemplateHash) 1885 result, err := state.blockTemplateResult(useCoinbaseValue, 1886 &submitOld) 1887 if err != nil { 1888 state.Unlock() 1889 return nil, err 1890 } 1891 1892 state.Unlock() 1893 return result, nil 1894 } 1895 1896 // Register the previous hash and last generated time for notifications 1897 // Get a channel that will be notified when the template associated with 1898 // the provided ID is stale and a new block template should be returned to 1899 // the caller. 1900 longPollChan := state.templateUpdateChan(prevHash, lastGenerated) 1901 state.Unlock() 1902 1903 select { 1904 // When the client closes before it's time to send a reply, just return 1905 // now so the goroutine doesn't hang around. 1906 case <-closeChan: 1907 return nil, ErrClientQuit 1908 1909 // Wait until signal received to send the reply. 1910 case <-longPollChan: 1911 // Fallthrough 1912 } 1913 1914 // Get the lastest block template 1915 state.Lock() 1916 defer state.Unlock() 1917 1918 if err := state.updateBlockTemplate(s, useCoinbaseValue); err != nil { 1919 return nil, err 1920 } 1921 1922 // Include whether or not it is valid to submit work against the old 1923 // block template depending on whether or not a solution has already 1924 // been found and added to the block chain. 1925 submitOld := prevHash.IsEqual(&state.template.Block.Header.PrevBlock) 1926 result, err := state.blockTemplateResult(useCoinbaseValue, &submitOld) 1927 if err != nil { 1928 return nil, err 1929 } 1930 1931 return result, nil 1932 } 1933 1934 // handleGetBlockTemplateRequest is a helper for handleGetBlockTemplate which 1935 // deals with generating and returning block templates to the caller. It 1936 // handles both long poll requests as specified by BIP 0022 as well as regular 1937 // requests. In addition, it detects the capabilities reported by the caller 1938 // in regards to whether or not it supports creating its own coinbase (the 1939 // coinbasetxn and coinbasevalue capabilities) and modifies the returned block 1940 // template accordingly. 1941 func handleGetBlockTemplateRequest(s *rpcServer, request *btcjson.TemplateRequest, closeChan <-chan struct{}) (interface{}, error) { 1942 // Extract the relevant passed capabilities and restrict the result to 1943 // either a coinbase value or a coinbase transaction object depending on 1944 // the request. Default to only providing a coinbase value. 1945 useCoinbaseValue := true 1946 if request != nil { 1947 var hasCoinbaseValue, hasCoinbaseTxn bool 1948 for _, capability := range request.Capabilities { 1949 switch capability { 1950 case "coinbasetxn": 1951 hasCoinbaseTxn = true 1952 case "coinbasevalue": 1953 hasCoinbaseValue = true 1954 } 1955 } 1956 1957 if hasCoinbaseTxn && !hasCoinbaseValue { 1958 useCoinbaseValue = false 1959 } 1960 } 1961 1962 // When a coinbase transaction has been requested, respond with an error 1963 // if there are no addresses to pay the created block template to. 1964 if !useCoinbaseValue && len(cfg.miningAddrs) == 0 { 1965 return nil, &btcjson.RPCError{ 1966 Code: btcjson.ErrRPCInternal.Code, 1967 Message: "A coinbase transaction has been requested, " + 1968 "but the server has not been configured with " + 1969 "any payment addresses via --miningaddr", 1970 } 1971 } 1972 1973 // Return an error if there are no peers connected since there is no 1974 // way to relay a found block or receive transactions to work on. 1975 // However, allow this state when running in the regression test or 1976 // simulation test mode. 1977 if !(cfg.RegressionTest || cfg.SimNet) && 1978 s.cfg.ConnMgr.ConnectedCount() == 0 { 1979 1980 return nil, &btcjson.RPCError{ 1981 Code: btcjson.ErrRPCClientNotConnected, 1982 Message: "Bitcoin is not connected", 1983 } 1984 } 1985 1986 // No point in generating or accepting work before the chain is synced. 1987 currentHeight := s.cfg.Chain.BestSnapshot().Height 1988 if currentHeight != 0 && !s.cfg.SyncMgr.IsCurrent() { 1989 return nil, &btcjson.RPCError{ 1990 Code: btcjson.ErrRPCClientInInitialDownload, 1991 Message: "Bitcoin is downloading blocks...", 1992 } 1993 } 1994 1995 // When a long poll ID was provided, this is a long poll request by the 1996 // client to be notified when block template referenced by the ID should 1997 // be replaced with a new one. 1998 if request != nil && request.LongPollID != "" { 1999 return handleGetBlockTemplateLongPoll(s, request.LongPollID, 2000 useCoinbaseValue, closeChan) 2001 } 2002 2003 // Protect concurrent access when updating block templates. 2004 state := s.gbtWorkState 2005 state.Lock() 2006 defer state.Unlock() 2007 2008 // Get and return a block template. A new block template will be 2009 // generated when the current best block has changed or the transactions 2010 // in the memory pool have been updated and it has been at least five 2011 // seconds since the last template was generated. Otherwise, the 2012 // timestamp for the existing block template is updated (and possibly 2013 // the difficulty on testnet per the consesus rules). 2014 if err := state.updateBlockTemplate(s, useCoinbaseValue); err != nil { 2015 return nil, err 2016 } 2017 return state.blockTemplateResult(useCoinbaseValue, nil) 2018 } 2019 2020 // chainErrToGBTErrString converts an error returned from btcchain to a string 2021 // which matches the reasons and format described in BIP0022 for rejection 2022 // reasons. 2023 func chainErrToGBTErrString(err error) string { 2024 // When the passed error is not a RuleError, just return a generic 2025 // rejected string with the error text. 2026 ruleErr, ok := err.(blockchain.RuleError) 2027 if !ok { 2028 return "rejected: " + err.Error() 2029 } 2030 2031 switch ruleErr.ErrorCode { 2032 case blockchain.ErrDuplicateBlock: 2033 return "duplicate" 2034 case blockchain.ErrBlockTooBig: 2035 return "bad-blk-length" 2036 case blockchain.ErrBlockWeightTooHigh: 2037 return "bad-blk-weight" 2038 case blockchain.ErrBlockVersionTooOld: 2039 return "bad-version" 2040 case blockchain.ErrInvalidTime: 2041 return "bad-time" 2042 case blockchain.ErrTimeTooOld: 2043 return "time-too-old" 2044 case blockchain.ErrTimeTooNew: 2045 return "time-too-new" 2046 case blockchain.ErrDifficultyTooLow: 2047 return "bad-diffbits" 2048 case blockchain.ErrUnexpectedDifficulty: 2049 return "bad-diffbits" 2050 case blockchain.ErrHighHash: 2051 return "high-hash" 2052 case blockchain.ErrBadMerkleRoot: 2053 return "bad-txnmrklroot" 2054 case blockchain.ErrBadCheckpoint: 2055 return "bad-checkpoint" 2056 case blockchain.ErrForkTooOld: 2057 return "fork-too-old" 2058 case blockchain.ErrCheckpointTimeTooOld: 2059 return "checkpoint-time-too-old" 2060 case blockchain.ErrNoTransactions: 2061 return "bad-txns-none" 2062 case blockchain.ErrNoTxInputs: 2063 return "bad-txns-noinputs" 2064 case blockchain.ErrNoTxOutputs: 2065 return "bad-txns-nooutputs" 2066 case blockchain.ErrTxTooBig: 2067 return "bad-txns-size" 2068 case blockchain.ErrBadTxOutValue: 2069 return "bad-txns-outputvalue" 2070 case blockchain.ErrDuplicateTxInputs: 2071 return "bad-txns-dupinputs" 2072 case blockchain.ErrBadTxInput: 2073 return "bad-txns-badinput" 2074 case blockchain.ErrMissingTxOut: 2075 return "bad-txns-missinginput" 2076 case blockchain.ErrUnfinalizedTx: 2077 return "bad-txns-unfinalizedtx" 2078 case blockchain.ErrDuplicateTx: 2079 return "bad-txns-duplicate" 2080 case blockchain.ErrOverwriteTx: 2081 return "bad-txns-overwrite" 2082 case blockchain.ErrImmatureSpend: 2083 return "bad-txns-maturity" 2084 case blockchain.ErrSpendTooHigh: 2085 return "bad-txns-highspend" 2086 case blockchain.ErrBadFees: 2087 return "bad-txns-fees" 2088 case blockchain.ErrTooManySigOps: 2089 return "high-sigops" 2090 case blockchain.ErrFirstTxNotCoinbase: 2091 return "bad-txns-nocoinbase" 2092 case blockchain.ErrMultipleCoinbases: 2093 return "bad-txns-multicoinbase" 2094 case blockchain.ErrBadCoinbaseScriptLen: 2095 return "bad-cb-length" 2096 case blockchain.ErrBadCoinbaseValue: 2097 return "bad-cb-value" 2098 case blockchain.ErrMissingCoinbaseHeight: 2099 return "bad-cb-height" 2100 case blockchain.ErrBadCoinbaseHeight: 2101 return "bad-cb-height" 2102 case blockchain.ErrScriptMalformed: 2103 return "bad-script-malformed" 2104 case blockchain.ErrScriptValidation: 2105 return "bad-script-validate" 2106 case blockchain.ErrUnexpectedWitness: 2107 return "unexpected-witness" 2108 case blockchain.ErrInvalidWitnessCommitment: 2109 return "bad-witness-nonce-size" 2110 case blockchain.ErrWitnessCommitmentMismatch: 2111 return "bad-witness-merkle-match" 2112 case blockchain.ErrPreviousBlockUnknown: 2113 return "prev-blk-not-found" 2114 case blockchain.ErrInvalidAncestorBlock: 2115 return "bad-prevblk" 2116 case blockchain.ErrPrevBlockNotBest: 2117 return "inconclusive-not-best-prvblk" 2118 } 2119 2120 return "rejected: " + err.Error() 2121 } 2122 2123 // handleGetBlockTemplateProposal is a helper for handleGetBlockTemplate which 2124 // deals with block proposals. 2125 // 2126 // See https://en.bitcoin.it/wiki/BIP_0023 for more details. 2127 func handleGetBlockTemplateProposal(s *rpcServer, request *btcjson.TemplateRequest) (interface{}, error) { 2128 hexData := request.Data 2129 if hexData == "" { 2130 return false, &btcjson.RPCError{ 2131 Code: btcjson.ErrRPCType, 2132 Message: fmt.Sprintf("Data must contain the " + 2133 "hex-encoded serialized block that is being " + 2134 "proposed"), 2135 } 2136 } 2137 2138 // Ensure the provided data is sane and deserialize the proposed block. 2139 if len(hexData)%2 != 0 { 2140 hexData = "0" + hexData 2141 } 2142 dataBytes, err := hex.DecodeString(hexData) 2143 if err != nil { 2144 return false, &btcjson.RPCError{ 2145 Code: btcjson.ErrRPCDeserialization, 2146 Message: fmt.Sprintf("Data must be "+ 2147 "hexadecimal string (not %q)", hexData), 2148 } 2149 } 2150 var msgBlock wire.MsgBlock 2151 if err := msgBlock.Deserialize(bytes.NewReader(dataBytes)); err != nil { 2152 return nil, &btcjson.RPCError{ 2153 Code: btcjson.ErrRPCDeserialization, 2154 Message: "Block decode failed: " + err.Error(), 2155 } 2156 } 2157 block := btcutil.NewBlock(&msgBlock) 2158 2159 // Ensure the block is building from the expected previous block. 2160 expectedPrevHash := s.cfg.Chain.BestSnapshot().Hash 2161 prevHash := &block.MsgBlock().Header.PrevBlock 2162 if !expectedPrevHash.IsEqual(prevHash) { 2163 return "bad-prevblk", nil 2164 } 2165 2166 if err := s.cfg.Chain.CheckConnectBlockTemplate(block); err != nil { 2167 if _, ok := err.(blockchain.RuleError); !ok { 2168 errStr := fmt.Sprintf("Failed to process block proposal: %v", err) 2169 rpcsLog.Error(errStr) 2170 return nil, &btcjson.RPCError{ 2171 Code: btcjson.ErrRPCVerify, 2172 Message: errStr, 2173 } 2174 } 2175 2176 rpcsLog.Infof("Rejected block proposal: %v", err) 2177 return chainErrToGBTErrString(err), nil 2178 } 2179 2180 return nil, nil 2181 } 2182 2183 // handleGetBlockTemplate implements the getblocktemplate command. 2184 // 2185 // See https://en.bitcoin.it/wiki/BIP_0022 and 2186 // https://en.bitcoin.it/wiki/BIP_0023 for more details. 2187 func handleGetBlockTemplate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2188 c := cmd.(*btcjson.GetBlockTemplateCmd) 2189 request := c.Request 2190 2191 // Set the default mode and override it if supplied. 2192 mode := "template" 2193 if request != nil && request.Mode != "" { 2194 mode = request.Mode 2195 } 2196 2197 switch mode { 2198 case "template": 2199 return handleGetBlockTemplateRequest(s, request, closeChan) 2200 case "proposal": 2201 return handleGetBlockTemplateProposal(s, request) 2202 } 2203 2204 return nil, &btcjson.RPCError{ 2205 Code: btcjson.ErrRPCInvalidParameter, 2206 Message: "Invalid mode", 2207 } 2208 } 2209 2210 // handleGetChainTips implements the getchaintips command. 2211 func handleGetChainTips(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2212 chainTips := s.cfg.Chain.ChainTips() 2213 2214 ret := make([]btcjson.GetChainTipsResult, 0, len(chainTips)) 2215 for _, chainTip := range chainTips { 2216 ret = append(ret, struct { 2217 Height int32 "json:\"height\"" 2218 Hash string "json:\"hash\"" 2219 BranchLen int32 "json:\"branchlen\"" 2220 Status string "json:\"status\"" 2221 }{ 2222 Height: chainTip.Height, 2223 Hash: chainTip.BlockHash.String(), 2224 BranchLen: chainTip.BranchLen, 2225 Status: chainTip.Status.String(), 2226 }) 2227 } 2228 2229 return ret, nil 2230 } 2231 2232 // handleGetCFilter implements the getcfilter command. 2233 func handleGetCFilter(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2234 if s.cfg.CfIndex == nil { 2235 return nil, &btcjson.RPCError{ 2236 Code: btcjson.ErrRPCNoCFIndex, 2237 Message: "The CF index must be enabled for this command", 2238 } 2239 } 2240 2241 c := cmd.(*btcjson.GetCFilterCmd) 2242 hash, err := chainhash.NewHashFromStr(c.Hash) 2243 if err != nil { 2244 return nil, rpcDecodeHexError(c.Hash) 2245 } 2246 2247 filterBytes, err := s.cfg.CfIndex.FilterByBlockHash(hash, c.FilterType) 2248 if err != nil { 2249 rpcsLog.Debugf("Could not find committed filter for %v: %v", 2250 hash, err) 2251 return nil, &btcjson.RPCError{ 2252 Code: btcjson.ErrRPCBlockNotFound, 2253 Message: "Block not found", 2254 } 2255 } 2256 2257 rpcsLog.Debugf("Found committed filter for %v", hash) 2258 return hex.EncodeToString(filterBytes), nil 2259 } 2260 2261 // handleGetCFilterHeader implements the getcfilterheader command. 2262 func handleGetCFilterHeader(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2263 if s.cfg.CfIndex == nil { 2264 return nil, &btcjson.RPCError{ 2265 Code: btcjson.ErrRPCNoCFIndex, 2266 Message: "The CF index must be enabled for this command", 2267 } 2268 } 2269 2270 c := cmd.(*btcjson.GetCFilterHeaderCmd) 2271 hash, err := chainhash.NewHashFromStr(c.Hash) 2272 if err != nil { 2273 return nil, rpcDecodeHexError(c.Hash) 2274 } 2275 2276 headerBytes, err := s.cfg.CfIndex.FilterHeaderByBlockHash(hash, c.FilterType) 2277 if len(headerBytes) > 0 { 2278 rpcsLog.Debugf("Found header of committed filter for %v", hash) 2279 } else { 2280 rpcsLog.Debugf("Could not find header of committed filter for %v: %v", 2281 hash, err) 2282 return nil, &btcjson.RPCError{ 2283 Code: btcjson.ErrRPCBlockNotFound, 2284 Message: "Block not found", 2285 } 2286 } 2287 2288 hash.SetBytes(headerBytes) 2289 return hash.String(), nil 2290 } 2291 2292 // handleGetConnectionCount implements the getconnectioncount command. 2293 func handleGetConnectionCount(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2294 return s.cfg.ConnMgr.ConnectedCount(), nil 2295 } 2296 2297 // handleGetCurrentNet implements the getcurrentnet command. 2298 func handleGetCurrentNet(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2299 return s.cfg.ChainParams.Net, nil 2300 } 2301 2302 // handleGetDifficulty implements the getdifficulty command. 2303 func handleGetDifficulty(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2304 best := s.cfg.Chain.BestSnapshot() 2305 return getDifficultyRatio(best.Bits, s.cfg.ChainParams), nil 2306 } 2307 2308 // handleGetGenerate implements the getgenerate command. 2309 func handleGetGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2310 return s.cfg.CPUMiner.IsMining(), nil 2311 } 2312 2313 // handleGetHashesPerSec implements the gethashespersec command. 2314 func handleGetHashesPerSec(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2315 return int64(s.cfg.CPUMiner.HashesPerSecond()), nil 2316 } 2317 2318 // handleGetHeaders implements the getheaders command. 2319 // 2320 // NOTE: This is a btcsuite extension originally ported from 2321 // github.com/decred/dcrd. 2322 func handleGetHeaders(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2323 c := cmd.(*btcjson.GetHeadersCmd) 2324 2325 // Fetch the requested headers from chain while respecting the provided 2326 // block locators and stop hash. 2327 blockLocators := make([]*chainhash.Hash, len(c.BlockLocators)) 2328 for i := range c.BlockLocators { 2329 blockLocator, err := chainhash.NewHashFromStr(c.BlockLocators[i]) 2330 if err != nil { 2331 return nil, rpcDecodeHexError(c.BlockLocators[i]) 2332 } 2333 blockLocators[i] = blockLocator 2334 } 2335 var hashStop chainhash.Hash 2336 if c.HashStop != "" { 2337 err := chainhash.Decode(&hashStop, c.HashStop) 2338 if err != nil { 2339 return nil, rpcDecodeHexError(c.HashStop) 2340 } 2341 } 2342 headers := s.cfg.SyncMgr.LocateHeaders(blockLocators, &hashStop) 2343 2344 // Return the serialized block headers as hex-encoded strings. 2345 hexBlockHeaders := make([]string, len(headers)) 2346 var buf bytes.Buffer 2347 for i, h := range headers { 2348 err := h.Serialize(&buf) 2349 if err != nil { 2350 return nil, internalRPCError(err.Error(), 2351 "Failed to serialize block header") 2352 } 2353 hexBlockHeaders[i] = hex.EncodeToString(buf.Bytes()) 2354 buf.Reset() 2355 } 2356 return hexBlockHeaders, nil 2357 } 2358 2359 // handleGetInfo implements the getinfo command. We only return the fields 2360 // that are not related to wallet functionality. 2361 func handleGetInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2362 best := s.cfg.Chain.BestSnapshot() 2363 ret := &btcjson.InfoChainResult{ 2364 Version: int32(1000000*appMajor + 10000*appMinor + 100*appPatch), 2365 ProtocolVersion: int32(maxProtocolVersion), 2366 Blocks: best.Height, 2367 TimeOffset: int64(s.cfg.TimeSource.Offset().Seconds()), 2368 Connections: s.cfg.ConnMgr.ConnectedCount(), 2369 Proxy: cfg.Proxy, 2370 Difficulty: getDifficultyRatio(best.Bits, s.cfg.ChainParams), 2371 TestNet: cfg.TestNet3, 2372 RelayFee: cfg.minRelayTxFee.ToBTC(), 2373 } 2374 2375 return ret, nil 2376 } 2377 2378 // handleGetMempoolInfo implements the getmempoolinfo command. 2379 func handleGetMempoolInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2380 mempoolTxns := s.cfg.TxMemPool.TxDescs() 2381 2382 var numBytes int64 2383 for _, txD := range mempoolTxns { 2384 numBytes += int64(txD.Tx.MsgTx().SerializeSize()) 2385 } 2386 2387 ret := &btcjson.GetMempoolInfoResult{ 2388 Size: int64(len(mempoolTxns)), 2389 Bytes: numBytes, 2390 } 2391 2392 return ret, nil 2393 } 2394 2395 // handleGetMiningInfo implements the getmininginfo command. We only return the 2396 // fields that are not related to wallet functionality. 2397 func handleGetMiningInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2398 // Create a default getnetworkhashps command to use defaults and make 2399 // use of the existing getnetworkhashps handler. 2400 gnhpsCmd := btcjson.NewGetNetworkHashPSCmd(nil, nil) 2401 networkHashesPerSecIface, err := handleGetNetworkHashPS(s, gnhpsCmd, 2402 closeChan) 2403 if err != nil { 2404 return nil, err 2405 } 2406 networkHashesPerSec, ok := networkHashesPerSecIface.(float64) 2407 if !ok { 2408 return nil, &btcjson.RPCError{ 2409 Code: btcjson.ErrRPCInternal.Code, 2410 Message: "networkHashesPerSec is not a float64", 2411 } 2412 } 2413 2414 best := s.cfg.Chain.BestSnapshot() 2415 result := btcjson.GetMiningInfoResult{ 2416 Blocks: int64(best.Height), 2417 CurrentBlockSize: best.BlockSize, 2418 CurrentBlockWeight: best.BlockWeight, 2419 CurrentBlockTx: best.NumTxns, 2420 Difficulty: getDifficultyRatio(best.Bits, s.cfg.ChainParams), 2421 Generate: s.cfg.CPUMiner.IsMining(), 2422 GenProcLimit: s.cfg.CPUMiner.NumWorkers(), 2423 HashesPerSec: s.cfg.CPUMiner.HashesPerSecond(), 2424 NetworkHashPS: networkHashesPerSec, 2425 PooledTx: uint64(s.cfg.TxMemPool.Count()), 2426 TestNet: cfg.TestNet3, 2427 } 2428 return &result, nil 2429 } 2430 2431 // handleGetNetTotals implements the getnettotals command. 2432 func handleGetNetTotals(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2433 totalBytesRecv, totalBytesSent := s.cfg.ConnMgr.NetTotals() 2434 reply := &btcjson.GetNetTotalsResult{ 2435 TotalBytesRecv: totalBytesRecv, 2436 TotalBytesSent: totalBytesSent, 2437 TimeMillis: time.Now().UTC().UnixNano() / int64(time.Millisecond), 2438 } 2439 return reply, nil 2440 } 2441 2442 // handleGetNetworkHashPS implements the getnetworkhashps command. 2443 func handleGetNetworkHashPS(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2444 // Note: All valid error return paths should return a float64. 2445 // Literal zeros are inferred as int, and won't coerce to float64 2446 // because the return value is an interface{}. 2447 2448 c := cmd.(*btcjson.GetNetworkHashPSCmd) 2449 2450 // When the passed height is too high or zero, just return 0 now 2451 // since we can't reasonably calculate the number of network hashes 2452 // per second from invalid values. When it's negative, use the current 2453 // best block height. 2454 best := s.cfg.Chain.BestSnapshot() 2455 endHeight := int32(-1) 2456 if c.Height != nil { 2457 endHeight = int32(*c.Height) 2458 } 2459 if endHeight > best.Height || endHeight == 0 { 2460 return float64(0), nil 2461 } 2462 if endHeight < 0 { 2463 endHeight = best.Height 2464 } 2465 2466 // Calculate the number of blocks per retarget interval based on the 2467 // chain parameters. 2468 blocksPerRetarget := int32(s.cfg.ChainParams.TargetTimespan / 2469 s.cfg.ChainParams.TargetTimePerBlock) 2470 2471 // Calculate the starting block height based on the passed number of 2472 // blocks. When the passed value is negative, use the last block the 2473 // difficulty changed as the starting height. Also make sure the 2474 // starting height is not before the beginning of the chain. 2475 numBlocks := int32(120) 2476 if c.Blocks != nil { 2477 numBlocks = int32(*c.Blocks) 2478 } 2479 var startHeight int32 2480 if numBlocks <= 0 { 2481 startHeight = endHeight - ((endHeight % blocksPerRetarget) + 1) 2482 } else { 2483 startHeight = endHeight - numBlocks 2484 } 2485 if startHeight < 0 { 2486 startHeight = 0 2487 } 2488 rpcsLog.Debugf("Calculating network hashes per second from %d to %d", 2489 startHeight, endHeight) 2490 2491 // Find the min and max block timestamps as well as calculate the total 2492 // amount of work that happened between the start and end blocks. 2493 var minTimestamp, maxTimestamp time.Time 2494 totalWork := big.NewInt(0) 2495 for curHeight := startHeight; curHeight <= endHeight; curHeight++ { 2496 hash, err := s.cfg.Chain.BlockHashByHeight(curHeight) 2497 if err != nil { 2498 context := "Failed to fetch block hash" 2499 return nil, internalRPCError(err.Error(), context) 2500 } 2501 2502 // Fetch the header from chain. 2503 header, err := s.cfg.Chain.HeaderByHash(hash) 2504 if err != nil { 2505 context := "Failed to fetch block header" 2506 return nil, internalRPCError(err.Error(), context) 2507 } 2508 2509 if curHeight == startHeight { 2510 minTimestamp = header.Timestamp 2511 maxTimestamp = minTimestamp 2512 } else { 2513 totalWork.Add(totalWork, blockchain.CalcWork(header.Bits)) 2514 2515 if minTimestamp.After(header.Timestamp) { 2516 minTimestamp = header.Timestamp 2517 } 2518 if maxTimestamp.Before(header.Timestamp) { 2519 maxTimestamp = header.Timestamp 2520 } 2521 } 2522 } 2523 2524 // Calculate the difference in seconds between the min and max block 2525 // timestamps and avoid division by zero in the case where there is no 2526 // time difference. 2527 timeDiff := maxTimestamp.Sub(minTimestamp).Seconds() 2528 if timeDiff == 0 { 2529 return timeDiff, nil 2530 } 2531 2532 hashesPerSec, _ := new(big.Float).Quo(new(big.Float).SetInt(totalWork), new(big.Float).SetFloat64(timeDiff)).Float64() 2533 return hashesPerSec, nil 2534 } 2535 2536 // handleGetNodeAddresses implements the getnodeaddresses command. 2537 func handleGetNodeAddresses(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2538 c := cmd.(*btcjson.GetNodeAddressesCmd) 2539 2540 count := int32(1) 2541 if c.Count != nil { 2542 count = *c.Count 2543 if count <= 0 { 2544 return nil, &btcjson.RPCError{ 2545 Code: btcjson.ErrRPCInvalidParameter, 2546 Message: "Address count out of range", 2547 } 2548 } 2549 } 2550 2551 nodes := s.cfg.ConnMgr.NodeAddresses() 2552 if n := int32(len(nodes)); n < count { 2553 count = n 2554 } 2555 2556 addresses := make([]*btcjson.GetNodeAddressesResult, 0, count) 2557 for _, node := range nodes[:count] { 2558 address := &btcjson.GetNodeAddressesResult{ 2559 Time: node.Timestamp.Unix(), 2560 Services: uint64(node.Services), 2561 Address: node.Addr.String(), 2562 Port: node.Port, 2563 } 2564 addresses = append(addresses, address) 2565 } 2566 2567 return addresses, nil 2568 } 2569 2570 // handleGetPeerInfo implements the getpeerinfo command. 2571 func handleGetPeerInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2572 peers := s.cfg.ConnMgr.ConnectedPeers() 2573 syncPeerID := s.cfg.SyncMgr.SyncPeerID() 2574 infos := make([]*btcjson.GetPeerInfoResult, 0, len(peers)) 2575 for _, p := range peers { 2576 statsSnap := p.ToPeer().StatsSnapshot() 2577 info := &btcjson.GetPeerInfoResult{ 2578 ID: statsSnap.ID, 2579 Addr: statsSnap.Addr, 2580 AddrLocal: p.ToPeer().LocalAddr().String(), 2581 Services: fmt.Sprintf("%08d", uint64(statsSnap.Services)), 2582 RelayTxes: !p.IsTxRelayDisabled(), 2583 LastSend: statsSnap.LastSend.Unix(), 2584 LastRecv: statsSnap.LastRecv.Unix(), 2585 BytesSent: statsSnap.BytesSent, 2586 BytesRecv: statsSnap.BytesRecv, 2587 ConnTime: statsSnap.ConnTime.Unix(), 2588 PingTime: float64(statsSnap.LastPingMicros), 2589 TimeOffset: statsSnap.TimeOffset, 2590 Version: statsSnap.Version, 2591 SubVer: statsSnap.UserAgent, 2592 Inbound: statsSnap.Inbound, 2593 StartingHeight: statsSnap.StartingHeight, 2594 CurrentHeight: statsSnap.LastBlock, 2595 BanScore: int32(p.BanScore()), 2596 FeeFilter: p.FeeFilter(), 2597 SyncNode: statsSnap.ID == syncPeerID, 2598 } 2599 if p.ToPeer().LastPingNonce() != 0 { 2600 wait := float64(time.Since(statsSnap.LastPingTime).Nanoseconds()) 2601 // We actually want microseconds. 2602 info.PingWait = wait / 1000 2603 } 2604 infos = append(infos, info) 2605 } 2606 return infos, nil 2607 } 2608 2609 // handleGetRawMempool implements the getrawmempool command. 2610 func handleGetRawMempool(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2611 c := cmd.(*btcjson.GetRawMempoolCmd) 2612 mp := s.cfg.TxMemPool 2613 2614 if c.Verbose != nil && *c.Verbose { 2615 return mp.RawMempoolVerbose(), nil 2616 } 2617 2618 // The response is simply an array of the transaction hashes if the 2619 // verbose flag is not set. 2620 descs := mp.TxDescs() 2621 hashStrings := make([]string, len(descs)) 2622 for i := range hashStrings { 2623 hashStrings[i] = descs[i].Tx.Hash().String() 2624 } 2625 2626 return hashStrings, nil 2627 } 2628 2629 // handleGetRawTransaction implements the getrawtransaction command. 2630 func handleGetRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2631 c := cmd.(*btcjson.GetRawTransactionCmd) 2632 2633 // Convert the provided transaction hash hex to a Hash. 2634 txHash, err := chainhash.NewHashFromStr(c.Txid) 2635 if err != nil { 2636 return nil, rpcDecodeHexError(c.Txid) 2637 } 2638 2639 verbose := false 2640 if c.Verbose != nil { 2641 verbose = *c.Verbose != 0 2642 } 2643 2644 // Try to fetch the transaction from the memory pool and if that fails, 2645 // try the block database. 2646 var mtx *wire.MsgTx 2647 var blkHash *chainhash.Hash 2648 var blkHeight int32 2649 tx, err := s.cfg.TxMemPool.FetchTransaction(txHash) 2650 if err != nil { 2651 if s.cfg.TxIndex == nil { 2652 return nil, &btcjson.RPCError{ 2653 Code: btcjson.ErrRPCNoTxInfo, 2654 Message: "The transaction index must be " + 2655 "enabled to query the blockchain " + 2656 "(specify --txindex)", 2657 } 2658 } 2659 2660 // Look up the location of the transaction. 2661 blockRegion, err := s.cfg.TxIndex.TxBlockRegion(txHash) 2662 if err != nil { 2663 context := "Failed to retrieve transaction location" 2664 return nil, internalRPCError(err.Error(), context) 2665 } 2666 if blockRegion == nil { 2667 return nil, rpcNoTxInfoError(txHash) 2668 } 2669 2670 // Load the raw transaction bytes from the database. 2671 var txBytes []byte 2672 err = s.cfg.DB.View(func(dbTx database.Tx) error { 2673 var err error 2674 txBytes, err = dbTx.FetchBlockRegion(blockRegion) 2675 return err 2676 }) 2677 if err != nil { 2678 return nil, rpcNoTxInfoError(txHash) 2679 } 2680 2681 // When the verbose flag isn't set, simply return the serialized 2682 // transaction as a hex-encoded string. This is done here to 2683 // avoid deserializing it only to reserialize it again later. 2684 if !verbose { 2685 return hex.EncodeToString(txBytes), nil 2686 } 2687 2688 // Grab the block height. 2689 blkHash = blockRegion.Hash 2690 blkHeight, err = s.cfg.Chain.BlockHeightByHash(blkHash) 2691 if err != nil { 2692 context := "Failed to retrieve block height" 2693 return nil, internalRPCError(err.Error(), context) 2694 } 2695 2696 // Deserialize the transaction 2697 var msgTx wire.MsgTx 2698 err = msgTx.Deserialize(bytes.NewReader(txBytes)) 2699 if err != nil { 2700 context := "Failed to deserialize transaction" 2701 return nil, internalRPCError(err.Error(), context) 2702 } 2703 mtx = &msgTx 2704 } else { 2705 // When the verbose flag isn't set, simply return the 2706 // network-serialized transaction as a hex-encoded string. 2707 if !verbose { 2708 // Note that this is intentionally not directly 2709 // returning because the first return value is a 2710 // string and it would result in returning an empty 2711 // string to the client instead of nothing (nil) in the 2712 // case of an error. 2713 mtxHex, err := messageToHex(tx.MsgTx()) 2714 if err != nil { 2715 return nil, err 2716 } 2717 return mtxHex, nil 2718 } 2719 2720 mtx = tx.MsgTx() 2721 } 2722 2723 // The verbose flag is set, so generate the JSON object and return it. 2724 var blkHeader *wire.BlockHeader 2725 var blkHashStr string 2726 var chainHeight int32 2727 if blkHash != nil { 2728 // Fetch the header from chain. 2729 header, err := s.cfg.Chain.HeaderByHash(blkHash) 2730 if err != nil { 2731 context := "Failed to fetch block header" 2732 return nil, internalRPCError(err.Error(), context) 2733 } 2734 2735 blkHeader = &header 2736 blkHashStr = blkHash.String() 2737 chainHeight = s.cfg.Chain.BestSnapshot().Height 2738 } 2739 2740 rawTxn, err := createTxRawResult(s.cfg.ChainParams, mtx, txHash.String(), 2741 blkHeader, blkHashStr, blkHeight, chainHeight) 2742 if err != nil { 2743 return nil, err 2744 } 2745 return *rawTxn, nil 2746 } 2747 2748 // handleGetTxOut handles gettxout commands. 2749 func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2750 c := cmd.(*btcjson.GetTxOutCmd) 2751 2752 // Convert the provided transaction hash hex to a Hash. 2753 txHash, err := chainhash.NewHashFromStr(c.Txid) 2754 if err != nil { 2755 return nil, rpcDecodeHexError(c.Txid) 2756 } 2757 2758 // If requested and the tx is available in the mempool try to fetch it 2759 // from there, otherwise attempt to fetch from the block database. 2760 var bestBlockHash string 2761 var confirmations int32 2762 var value int64 2763 var pkScript []byte 2764 var isCoinbase bool 2765 var address string 2766 includeMempool := true 2767 if c.IncludeMempool != nil { 2768 includeMempool = *c.IncludeMempool 2769 } 2770 // TODO: This is racy. It should attempt to fetch it directly and check 2771 // the error. 2772 if includeMempool && s.cfg.TxMemPool.HaveTransaction(txHash) { 2773 tx, err := s.cfg.TxMemPool.FetchTransaction(txHash) 2774 if err != nil { 2775 return nil, rpcNoTxInfoError(txHash) 2776 } 2777 2778 mtx := tx.MsgTx() 2779 if c.Vout > uint32(len(mtx.TxOut)-1) { 2780 return nil, &btcjson.RPCError{ 2781 Code: btcjson.ErrRPCInvalidTxVout, 2782 Message: "Output index number (vout) does not " + 2783 "exist for transaction.", 2784 } 2785 } 2786 2787 txOut := mtx.TxOut[c.Vout] 2788 if txOut == nil { 2789 errStr := fmt.Sprintf("Output index: %d for txid: %s "+ 2790 "does not exist", c.Vout, txHash) 2791 return nil, internalRPCError(errStr, "") 2792 } 2793 2794 best := s.cfg.Chain.BestSnapshot() 2795 bestBlockHash = best.Hash.String() 2796 confirmations = 0 2797 value = txOut.Value 2798 pkScript = txOut.PkScript 2799 isCoinbase = blockchain.IsCoinBaseTx(mtx) 2800 } else { 2801 out := wire.OutPoint{Hash: *txHash, Index: c.Vout} 2802 entry, err := s.cfg.Chain.FetchUtxoEntry(out) 2803 if err != nil { 2804 return nil, rpcNoTxInfoError(txHash) 2805 } 2806 2807 // To match the behavior of the reference client, return nil 2808 // (JSON null) if the transaction output is spent by another 2809 // transaction already in the main chain. Mined transactions 2810 // that are spent by a mempool transaction are not affected by 2811 // this. 2812 if entry == nil || entry.IsSpent() { 2813 return nil, nil 2814 } 2815 2816 best := s.cfg.Chain.BestSnapshot() 2817 bestBlockHash = best.Hash.String() 2818 confirmations = 1 + best.Height - entry.BlockHeight() 2819 value = entry.Amount() 2820 pkScript = entry.PkScript() 2821 isCoinbase = entry.IsCoinBase() 2822 } 2823 2824 // Disassemble script into single line printable format. 2825 // The disassembled string will contain [error] inline if the script 2826 // doesn't fully parse, so ignore the error here. 2827 disbuf, _ := txscript.DisasmString(pkScript) 2828 2829 // Get further info about the script. 2830 // Ignore the error here since an error means the script couldn't parse 2831 // and there is no additional information about it anyways. 2832 scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(pkScript, 2833 s.cfg.ChainParams) 2834 addresses := make([]string, len(addrs)) 2835 for i, addr := range addrs { 2836 addresses[i] = addr.EncodeAddress() 2837 } 2838 2839 // Address is defined when there's a single well-defined 2840 // receiver address. To spend the output a signature for this, 2841 // and only this, address is required. 2842 if len(addresses) == 1 && reqSigs <= 1 { 2843 address = addresses[0] 2844 } 2845 2846 txOutReply := &btcjson.GetTxOutResult{ 2847 BestBlock: bestBlockHash, 2848 Confirmations: int64(confirmations), 2849 Value: btcutil.Amount(value).ToBTC(), 2850 ScriptPubKey: btcjson.ScriptPubKeyResult{ 2851 Asm: disbuf, 2852 Hex: hex.EncodeToString(pkScript), 2853 ReqSigs: int32(reqSigs), 2854 Type: scriptClass.String(), 2855 Address: address, 2856 Addresses: addresses, 2857 }, 2858 Coinbase: isCoinbase, 2859 } 2860 2861 return txOutReply, nil 2862 } 2863 2864 // handleHelp implements the help command. 2865 func handleHelp(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2866 c := cmd.(*btcjson.HelpCmd) 2867 2868 // Provide a usage overview of all commands when no specific command 2869 // was specified. 2870 var command string 2871 if c.Command != nil { 2872 command = *c.Command 2873 } 2874 if command == "" { 2875 usage, err := s.helpCacher.rpcUsage(false) 2876 if err != nil { 2877 context := "Failed to generate RPC usage" 2878 return nil, internalRPCError(err.Error(), context) 2879 } 2880 return usage, nil 2881 } 2882 2883 // Check that the command asked for is supported and implemented. Only 2884 // search the main list of handlers since help should not be provided 2885 // for commands that are unimplemented or related to wallet 2886 // functionality. 2887 if _, ok := rpcHandlers[command]; !ok { 2888 return nil, &btcjson.RPCError{ 2889 Code: btcjson.ErrRPCInvalidParameter, 2890 Message: "Unknown command: " + command, 2891 } 2892 } 2893 2894 // Get the help for the command. 2895 help, err := s.helpCacher.rpcMethodHelp(command) 2896 if err != nil { 2897 context := "Failed to generate help" 2898 return nil, internalRPCError(err.Error(), context) 2899 } 2900 return help, nil 2901 } 2902 2903 // handlePing implements the ping command. 2904 func handlePing(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 2905 // Ask server to ping \o_ 2906 nonce, err := wire.RandomUint64() 2907 if err != nil { 2908 return nil, internalRPCError("Not sending ping - failed to "+ 2909 "generate nonce: "+err.Error(), "") 2910 } 2911 s.cfg.ConnMgr.BroadcastMessage(wire.NewMsgPing(nonce)) 2912 2913 return nil, nil 2914 } 2915 2916 // retrievedTx represents a transaction that was either loaded from the 2917 // transaction memory pool or from the database. When a transaction is loaded 2918 // from the database, it is loaded with the raw serialized bytes while the 2919 // mempool has the fully deserialized structure. This structure therefore will 2920 // have one of the two fields set depending on where is was retrieved from. 2921 // This is mainly done for efficiency to avoid extra serialization steps when 2922 // possible. 2923 type retrievedTx struct { 2924 txBytes []byte 2925 blkHash *chainhash.Hash // Only set when transaction is in a block. 2926 tx *btcutil.Tx 2927 } 2928 2929 // fetchInputTxos fetches the outpoints from all transactions referenced by the 2930 // inputs to the passed transaction by checking the transaction mempool first 2931 // then the transaction index for those already mined into blocks. 2932 func fetchInputTxos(s *rpcServer, tx *wire.MsgTx) (map[wire.OutPoint]wire.TxOut, error) { 2933 mp := s.cfg.TxMemPool 2934 originOutputs := make(map[wire.OutPoint]wire.TxOut) 2935 for txInIndex, txIn := range tx.TxIn { 2936 // Attempt to fetch and use the referenced transaction from the 2937 // memory pool. 2938 origin := &txIn.PreviousOutPoint 2939 originTx, err := mp.FetchTransaction(&origin.Hash) 2940 if err == nil { 2941 txOuts := originTx.MsgTx().TxOut 2942 if origin.Index >= uint32(len(txOuts)) { 2943 errStr := fmt.Sprintf("unable to find output "+ 2944 "%v referenced from transaction %s:%d", 2945 origin, tx.TxHash(), txInIndex) 2946 return nil, internalRPCError(errStr, "") 2947 } 2948 2949 originOutputs[*origin] = *txOuts[origin.Index] 2950 continue 2951 } 2952 2953 // Look up the location of the transaction. 2954 blockRegion, err := s.cfg.TxIndex.TxBlockRegion(&origin.Hash) 2955 if err != nil { 2956 context := "Failed to retrieve transaction location" 2957 return nil, internalRPCError(err.Error(), context) 2958 } 2959 if blockRegion == nil { 2960 return nil, rpcNoTxInfoError(&origin.Hash) 2961 } 2962 2963 // Load the raw transaction bytes from the database. 2964 var txBytes []byte 2965 err = s.cfg.DB.View(func(dbTx database.Tx) error { 2966 var err error 2967 txBytes, err = dbTx.FetchBlockRegion(blockRegion) 2968 return err 2969 }) 2970 if err != nil { 2971 return nil, rpcNoTxInfoError(&origin.Hash) 2972 } 2973 2974 // Deserialize the transaction 2975 var msgTx wire.MsgTx 2976 err = msgTx.Deserialize(bytes.NewReader(txBytes)) 2977 if err != nil { 2978 context := "Failed to deserialize transaction" 2979 return nil, internalRPCError(err.Error(), context) 2980 } 2981 2982 // Add the referenced output to the map. 2983 if origin.Index >= uint32(len(msgTx.TxOut)) { 2984 errStr := fmt.Sprintf("unable to find output %v "+ 2985 "referenced from transaction %s:%d", origin, 2986 tx.TxHash(), txInIndex) 2987 return nil, internalRPCError(errStr, "") 2988 } 2989 originOutputs[*origin] = *msgTx.TxOut[origin.Index] 2990 } 2991 2992 return originOutputs, nil 2993 } 2994 2995 // createVinListPrevOut returns a slice of JSON objects for the inputs of the 2996 // passed transaction. 2997 func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.Params, vinExtra bool, filterAddrMap map[string]struct{}) ([]btcjson.VinPrevOut, error) { 2998 // Coinbase transactions only have a single txin by definition. 2999 if blockchain.IsCoinBaseTx(mtx) { 3000 // Only include the transaction if the filter map is empty 3001 // because a coinbase input has no addresses and so would never 3002 // match a non-empty filter. 3003 if len(filterAddrMap) != 0 { 3004 return nil, nil 3005 } 3006 3007 txIn := mtx.TxIn[0] 3008 vinList := make([]btcjson.VinPrevOut, 1) 3009 vinList[0].Coinbase = hex.EncodeToString(txIn.SignatureScript) 3010 vinList[0].Sequence = txIn.Sequence 3011 return vinList, nil 3012 } 3013 3014 // Use a dynamically sized list to accommodate the address filter. 3015 vinList := make([]btcjson.VinPrevOut, 0, len(mtx.TxIn)) 3016 3017 // Lookup all of the referenced transaction outputs needed to populate 3018 // the previous output information if requested. 3019 var originOutputs map[wire.OutPoint]wire.TxOut 3020 if vinExtra || len(filterAddrMap) > 0 { 3021 var err error 3022 originOutputs, err = fetchInputTxos(s, mtx) 3023 if err != nil { 3024 return nil, err 3025 } 3026 } 3027 3028 for _, txIn := range mtx.TxIn { 3029 // The disassembled string will contain [error] inline 3030 // if the script doesn't fully parse, so ignore the 3031 // error here. 3032 disbuf, _ := txscript.DisasmString(txIn.SignatureScript) 3033 3034 // Create the basic input entry without the additional optional 3035 // previous output details which will be added later if 3036 // requested and available. 3037 prevOut := &txIn.PreviousOutPoint 3038 vinEntry := btcjson.VinPrevOut{ 3039 Txid: prevOut.Hash.String(), 3040 Vout: prevOut.Index, 3041 Sequence: txIn.Sequence, 3042 ScriptSig: &btcjson.ScriptSig{ 3043 Asm: disbuf, 3044 Hex: hex.EncodeToString(txIn.SignatureScript), 3045 }, 3046 } 3047 3048 if len(txIn.Witness) != 0 { 3049 vinEntry.Witness = witnessToHex(txIn.Witness) 3050 } 3051 3052 // Add the entry to the list now if it already passed the filter 3053 // since the previous output might not be available. 3054 passesFilter := len(filterAddrMap) == 0 3055 if passesFilter { 3056 vinList = append(vinList, vinEntry) 3057 } 3058 3059 // Only populate previous output information if requested and 3060 // available. 3061 if len(originOutputs) == 0 { 3062 continue 3063 } 3064 originTxOut, ok := originOutputs[*prevOut] 3065 if !ok { 3066 continue 3067 } 3068 3069 // Ignore the error here since an error means the script 3070 // couldn't parse and there is no additional information about 3071 // it anyways. 3072 _, addrs, _, _ := txscript.ExtractPkScriptAddrs( 3073 originTxOut.PkScript, chainParams) 3074 3075 // Encode the addresses while checking if the address passes the 3076 // filter when needed. 3077 encodedAddrs := make([]string, len(addrs)) 3078 for j, addr := range addrs { 3079 encodedAddr := addr.EncodeAddress() 3080 encodedAddrs[j] = encodedAddr 3081 3082 // No need to check the map again if the filter already 3083 // passes. 3084 if passesFilter { 3085 continue 3086 } 3087 if _, exists := filterAddrMap[encodedAddr]; exists { 3088 passesFilter = true 3089 } 3090 } 3091 3092 // Ignore the entry if it doesn't pass the filter. 3093 if !passesFilter { 3094 continue 3095 } 3096 3097 // Add entry to the list if it wasn't already done above. 3098 if len(filterAddrMap) != 0 { 3099 vinList = append(vinList, vinEntry) 3100 } 3101 3102 // Update the entry with previous output information if 3103 // requested. 3104 if vinExtra { 3105 vinListEntry := &vinList[len(vinList)-1] 3106 vinListEntry.PrevOut = &btcjson.PrevOut{ 3107 Addresses: encodedAddrs, 3108 Value: btcutil.Amount(originTxOut.Value).ToBTC(), 3109 } 3110 } 3111 } 3112 3113 return vinList, nil 3114 } 3115 3116 // fetchMempoolTxnsForAddress queries the address index for all unconfirmed 3117 // transactions that involve the provided address. The results will be limited 3118 // by the number to skip and the number requested. 3119 func fetchMempoolTxnsForAddress(s *rpcServer, addr btcutil.Address, numToSkip, numRequested uint32) ([]*btcutil.Tx, uint32) { 3120 // There are no entries to return when there are less available than the 3121 // number being skipped. 3122 mpTxns := s.cfg.AddrIndex.UnconfirmedTxnsForAddress(addr) 3123 numAvailable := uint32(len(mpTxns)) 3124 if numToSkip > numAvailable { 3125 return nil, numAvailable 3126 } 3127 3128 // Filter the available entries based on the number to skip and number 3129 // requested. 3130 rangeEnd := numToSkip + numRequested 3131 if rangeEnd > numAvailable { 3132 rangeEnd = numAvailable 3133 } 3134 return mpTxns[numToSkip:rangeEnd], numToSkip 3135 } 3136 3137 // handleSearchRawTransactions implements the searchrawtransactions command. 3138 func handleSearchRawTransactions(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 3139 // Respond with an error if the address index is not enabled. 3140 addrIndex := s.cfg.AddrIndex 3141 if addrIndex == nil { 3142 return nil, &btcjson.RPCError{ 3143 Code: btcjson.ErrRPCMisc, 3144 Message: "Address index must be enabled (--addrindex)", 3145 } 3146 } 3147 3148 // Override the flag for including extra previous output information in 3149 // each input if needed. 3150 c := cmd.(*btcjson.SearchRawTransactionsCmd) 3151 vinExtra := false 3152 if c.VinExtra != nil { 3153 vinExtra = *c.VinExtra != 0 3154 } 3155 3156 // Including the extra previous output information requires the 3157 // transaction index. Currently the address index relies on the 3158 // transaction index, so this check is redundant, but it's better to be 3159 // safe in case the address index is ever changed to not rely on it. 3160 if vinExtra && s.cfg.TxIndex == nil { 3161 return nil, &btcjson.RPCError{ 3162 Code: btcjson.ErrRPCMisc, 3163 Message: "Transaction index must be enabled (--txindex)", 3164 } 3165 } 3166 3167 // Attempt to decode the supplied address. 3168 params := s.cfg.ChainParams 3169 addr, err := btcutil.DecodeAddress(c.Address, params) 3170 if err != nil { 3171 return nil, &btcjson.RPCError{ 3172 Code: btcjson.ErrRPCInvalidAddressOrKey, 3173 Message: "Invalid address or key: " + err.Error(), 3174 } 3175 } 3176 3177 // Override the default number of requested entries if needed. Also, 3178 // just return now if the number of requested entries is zero to avoid 3179 // extra work. 3180 numRequested := 100 3181 if c.Count != nil { 3182 numRequested = *c.Count 3183 if numRequested < 0 { 3184 numRequested = 1 3185 } 3186 } 3187 if numRequested == 0 { 3188 return nil, nil 3189 } 3190 3191 // Override the default number of entries to skip if needed. 3192 var numToSkip int 3193 if c.Skip != nil { 3194 numToSkip = *c.Skip 3195 if numToSkip < 0 { 3196 numToSkip = 0 3197 } 3198 } 3199 3200 // Override the reverse flag if needed. 3201 var reverse bool 3202 if c.Reverse != nil { 3203 reverse = *c.Reverse 3204 } 3205 3206 // Add transactions from mempool first if client asked for reverse 3207 // order. Otherwise, they will be added last (as needed depending on 3208 // the requested counts). 3209 // 3210 // NOTE: This code doesn't sort by dependency. This might be something 3211 // to do in the future for the client's convenience, or leave it to the 3212 // client. 3213 numSkipped := uint32(0) 3214 addressTxns := make([]retrievedTx, 0, numRequested) 3215 if reverse { 3216 // Transactions in the mempool are not in a block header yet, 3217 // so the block header field in the retieved transaction struct 3218 // is left nil. 3219 mpTxns, mpSkipped := fetchMempoolTxnsForAddress(s, addr, 3220 uint32(numToSkip), uint32(numRequested)) 3221 numSkipped += mpSkipped 3222 for _, tx := range mpTxns { 3223 addressTxns = append(addressTxns, retrievedTx{tx: tx}) 3224 } 3225 } 3226 3227 // Fetch transactions from the database in the desired order if more are 3228 // needed. 3229 if len(addressTxns) < numRequested { 3230 err = s.cfg.DB.View(func(dbTx database.Tx) error { 3231 regions, dbSkipped, err := addrIndex.TxRegionsForAddress( 3232 dbTx, addr, uint32(numToSkip)-numSkipped, 3233 uint32(numRequested-len(addressTxns)), reverse) 3234 if err != nil { 3235 return err 3236 } 3237 3238 // Load the raw transaction bytes from the database. 3239 serializedTxns, err := dbTx.FetchBlockRegions(regions) 3240 if err != nil { 3241 return err 3242 } 3243 3244 // Add the transaction and the hash of the block it is 3245 // contained in to the list. Note that the transaction 3246 // is left serialized here since the caller might have 3247 // requested non-verbose output and hence there would be 3248 // no point in deserializing it just to reserialize it 3249 // later. 3250 for i, serializedTx := range serializedTxns { 3251 addressTxns = append(addressTxns, retrievedTx{ 3252 txBytes: serializedTx, 3253 blkHash: regions[i].Hash, 3254 }) 3255 } 3256 numSkipped += dbSkipped 3257 3258 return nil 3259 }) 3260 if err != nil { 3261 context := "Failed to load address index entries" 3262 return nil, internalRPCError(err.Error(), context) 3263 } 3264 3265 } 3266 3267 // Add transactions from mempool last if client did not request reverse 3268 // order and the number of results is still under the number requested. 3269 if !reverse && len(addressTxns) < numRequested { 3270 // Transactions in the mempool are not in a block header yet, 3271 // so the block header field in the retieved transaction struct 3272 // is left nil. 3273 mpTxns, mpSkipped := fetchMempoolTxnsForAddress(s, addr, 3274 uint32(numToSkip)-numSkipped, uint32(numRequested- 3275 len(addressTxns))) 3276 numSkipped += mpSkipped 3277 for _, tx := range mpTxns { 3278 addressTxns = append(addressTxns, retrievedTx{tx: tx}) 3279 } 3280 } 3281 3282 // Address has never been used if neither source yielded any results. 3283 if len(addressTxns) == 0 { 3284 return nil, &btcjson.RPCError{ 3285 Code: btcjson.ErrRPCNoTxInfo, 3286 Message: "No information available about address", 3287 } 3288 } 3289 3290 // Serialize all of the transactions to hex. 3291 hexTxns := make([]string, len(addressTxns)) 3292 for i := range addressTxns { 3293 // Simply encode the raw bytes to hex when the retrieved 3294 // transaction is already in serialized form. 3295 rtx := &addressTxns[i] 3296 if rtx.txBytes != nil { 3297 hexTxns[i] = hex.EncodeToString(rtx.txBytes) 3298 continue 3299 } 3300 3301 // Serialize the transaction first and convert to hex when the 3302 // retrieved transaction is the deserialized structure. 3303 hexTxns[i], err = messageToHex(rtx.tx.MsgTx()) 3304 if err != nil { 3305 return nil, err 3306 } 3307 } 3308 3309 // When not in verbose mode, simply return a list of serialized txns. 3310 if c.Verbose != nil && *c.Verbose == 0 { 3311 return hexTxns, nil 3312 } 3313 3314 // Normalize the provided filter addresses (if any) to ensure there are 3315 // no duplicates. 3316 filterAddrMap := make(map[string]struct{}) 3317 if c.FilterAddrs != nil && len(*c.FilterAddrs) > 0 { 3318 for _, addr := range *c.FilterAddrs { 3319 filterAddrMap[addr] = struct{}{} 3320 } 3321 } 3322 3323 // The verbose flag is set, so generate the JSON object and return it. 3324 best := s.cfg.Chain.BestSnapshot() 3325 srtList := make([]btcjson.SearchRawTransactionsResult, len(addressTxns)) 3326 for i := range addressTxns { 3327 // The deserialized transaction is needed, so deserialize the 3328 // retrieved transaction if it's in serialized form (which will 3329 // be the case when it was lookup up from the database). 3330 // Otherwise, use the existing deserialized transaction. 3331 rtx := &addressTxns[i] 3332 var mtx *wire.MsgTx 3333 if rtx.tx == nil { 3334 // Deserialize the transaction. 3335 mtx = new(wire.MsgTx) 3336 err := mtx.Deserialize(bytes.NewReader(rtx.txBytes)) 3337 if err != nil { 3338 context := "Failed to deserialize transaction" 3339 return nil, internalRPCError(err.Error(), 3340 context) 3341 } 3342 } else { 3343 mtx = rtx.tx.MsgTx() 3344 } 3345 3346 result := &srtList[i] 3347 result.Hex = hexTxns[i] 3348 result.Txid = mtx.TxHash().String() 3349 result.Vin, err = createVinListPrevOut(s, mtx, params, vinExtra, 3350 filterAddrMap) 3351 if err != nil { 3352 return nil, err 3353 } 3354 result.Vout = createVoutList(mtx, params, filterAddrMap) 3355 result.Version = mtx.Version 3356 result.LockTime = mtx.LockTime 3357 3358 // Transactions grabbed from the mempool aren't yet in a block, 3359 // so conditionally fetch block details here. This will be 3360 // reflected in the final JSON output (mempool won't have 3361 // confirmations or block information). 3362 var blkHeader *wire.BlockHeader 3363 var blkHashStr string 3364 var blkHeight int32 3365 if blkHash := rtx.blkHash; blkHash != nil { 3366 // Fetch the header from chain. 3367 header, err := s.cfg.Chain.HeaderByHash(blkHash) 3368 if err != nil { 3369 return nil, &btcjson.RPCError{ 3370 Code: btcjson.ErrRPCBlockNotFound, 3371 Message: "Block not found", 3372 } 3373 } 3374 3375 // Get the block height from chain. 3376 height, err := s.cfg.Chain.BlockHeightByHash(blkHash) 3377 if err != nil { 3378 context := "Failed to obtain block height" 3379 return nil, internalRPCError(err.Error(), context) 3380 } 3381 3382 blkHeader = &header 3383 blkHashStr = blkHash.String() 3384 blkHeight = height 3385 } 3386 3387 // Add the block information to the result if there is any. 3388 if blkHeader != nil { 3389 // This is not a typo, they are identical in Bitcoin 3390 // Core as well. 3391 result.Time = blkHeader.Timestamp.Unix() 3392 result.Blocktime = blkHeader.Timestamp.Unix() 3393 result.BlockHash = blkHashStr 3394 result.Confirmations = uint64(1 + best.Height - blkHeight) 3395 } 3396 } 3397 3398 return srtList, nil 3399 } 3400 3401 // handleSendRawTransaction implements the sendrawtransaction command. 3402 func handleSendRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 3403 c := cmd.(*btcjson.SendRawTransactionCmd) 3404 // Deserialize and send off to tx relay 3405 hexStr := c.HexTx 3406 if len(hexStr)%2 != 0 { 3407 hexStr = "0" + hexStr 3408 } 3409 serializedTx, err := hex.DecodeString(hexStr) 3410 if err != nil { 3411 return nil, rpcDecodeHexError(hexStr) 3412 } 3413 var msgTx wire.MsgTx 3414 err = msgTx.Deserialize(bytes.NewReader(serializedTx)) 3415 if err != nil { 3416 return nil, &btcjson.RPCError{ 3417 Code: btcjson.ErrRPCDeserialization, 3418 Message: "TX decode failed: " + err.Error(), 3419 } 3420 } 3421 3422 // Use 0 for the tag to represent local node. 3423 tx := btcutil.NewTx(&msgTx) 3424 acceptedTxs, err := s.cfg.TxMemPool.ProcessTransaction(tx, false, false, 0) 3425 if err != nil { 3426 // When the error is a rule error, it means the transaction was 3427 // simply rejected as opposed to something actually going wrong, 3428 // so log it as such. Otherwise, something really did go wrong, 3429 // so log it as an actual error and return. 3430 ruleErr, ok := err.(mempool.RuleError) 3431 if !ok { 3432 rpcsLog.Errorf("Failed to process transaction %v: %v", 3433 tx.Hash(), err) 3434 3435 return nil, &btcjson.RPCError{ 3436 Code: btcjson.ErrRPCTxError, 3437 Message: "TX rejected: " + err.Error(), 3438 } 3439 } 3440 3441 rpcsLog.Debugf("Rejected transaction %v: %v", tx.Hash(), err) 3442 3443 // We'll then map the rule error to the appropriate RPC error, 3444 // matching bitcoind's behavior. 3445 code := btcjson.ErrRPCTxError 3446 if txRuleErr, ok := ruleErr.Err.(mempool.TxRuleError); ok { 3447 errDesc := txRuleErr.Description 3448 switch { 3449 case strings.Contains( 3450 strings.ToLower(errDesc), "orphan transaction", 3451 ): 3452 code = btcjson.ErrRPCTxError 3453 3454 case strings.Contains( 3455 strings.ToLower(errDesc), "transaction already exists", 3456 ): 3457 code = btcjson.ErrRPCTxAlreadyInChain 3458 3459 default: 3460 code = btcjson.ErrRPCTxRejected 3461 } 3462 } 3463 3464 return nil, &btcjson.RPCError{ 3465 Code: code, 3466 Message: "TX rejected: " + err.Error(), 3467 } 3468 } 3469 3470 // When the transaction was accepted it should be the first item in the 3471 // returned array of accepted transactions. The only way this will not 3472 // be true is if the API for ProcessTransaction changes and this code is 3473 // not properly updated, but ensure the condition holds as a safeguard. 3474 // 3475 // Also, since an error is being returned to the caller, ensure the 3476 // transaction is removed from the memory pool. 3477 if len(acceptedTxs) == 0 || !acceptedTxs[0].Tx.Hash().IsEqual(tx.Hash()) { 3478 s.cfg.TxMemPool.RemoveTransaction(tx, true) 3479 3480 errStr := fmt.Sprintf("transaction %v is not in accepted list", 3481 tx.Hash()) 3482 return nil, internalRPCError(errStr, "") 3483 } 3484 3485 // Generate and relay inventory vectors for all newly accepted 3486 // transactions into the memory pool due to the original being 3487 // accepted. 3488 s.cfg.ConnMgr.RelayTransactions(acceptedTxs) 3489 3490 // Notify both websocket and getblocktemplate long poll clients of all 3491 // newly accepted transactions. 3492 s.NotifyNewTransactions(acceptedTxs) 3493 3494 // Keep track of all the sendrawtransaction request txns so that they 3495 // can be rebroadcast if they don't make their way into a block. 3496 txD := acceptedTxs[0] 3497 iv := wire.NewInvVect(wire.InvTypeTx, txD.Tx.Hash()) 3498 s.cfg.ConnMgr.AddRebroadcastInventory(iv, txD) 3499 3500 return tx.Hash().String(), nil 3501 } 3502 3503 // handleSetGenerate implements the setgenerate command. 3504 func handleSetGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 3505 c := cmd.(*btcjson.SetGenerateCmd) 3506 3507 // Disable generation regardless of the provided generate flag if the 3508 // maximum number of threads (goroutines for our purposes) is 0. 3509 // Otherwise enable or disable it depending on the provided flag. 3510 generate := c.Generate 3511 genProcLimit := -1 3512 if c.GenProcLimit != nil { 3513 genProcLimit = *c.GenProcLimit 3514 } 3515 if genProcLimit == 0 { 3516 generate = false 3517 } 3518 3519 if !generate { 3520 s.cfg.CPUMiner.Stop() 3521 } else { 3522 // Respond with an error if there are no addresses to pay the 3523 // created blocks to. 3524 if len(cfg.miningAddrs) == 0 { 3525 return nil, &btcjson.RPCError{ 3526 Code: btcjson.ErrRPCInternal.Code, 3527 Message: "No payment addresses specified " + 3528 "via --miningaddr", 3529 } 3530 } 3531 3532 // It's safe to call start even if it's already started. 3533 s.cfg.CPUMiner.SetNumWorkers(int32(genProcLimit)) 3534 s.cfg.CPUMiner.Start() 3535 } 3536 return nil, nil 3537 } 3538 3539 // Text used to signify that a signed message follows and to prevent 3540 // inadvertently signing a transaction. 3541 const messageSignatureHeader = "Bitcoin Signed Message:\n" 3542 3543 // handleSignMessageWithPrivKey implements the signmessagewithprivkey command. 3544 func handleSignMessageWithPrivKey(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 3545 c := cmd.(*btcjson.SignMessageWithPrivKeyCmd) 3546 3547 wif, err := btcutil.DecodeWIF(c.PrivKey) 3548 if err != nil { 3549 message := "Invalid private key" 3550 switch err { 3551 case btcutil.ErrMalformedPrivateKey: 3552 message = "Malformed private key" 3553 case btcutil.ErrChecksumMismatch: 3554 message = "Private key checksum mismatch" 3555 } 3556 return nil, &btcjson.RPCError{ 3557 Code: btcjson.ErrRPCInvalidAddressOrKey, 3558 Message: message, 3559 } 3560 } 3561 if !wif.IsForNet(s.cfg.ChainParams) { 3562 return nil, &btcjson.RPCError{ 3563 Code: btcjson.ErrRPCInvalidAddressOrKey, 3564 Message: "Private key for wrong network", 3565 } 3566 } 3567 3568 var buf bytes.Buffer 3569 wire.WriteVarString(&buf, 0, messageSignatureHeader) 3570 wire.WriteVarString(&buf, 0, c.Message) 3571 messageHash := chainhash.DoubleHashB(buf.Bytes()) 3572 3573 sig, err := ecdsa.SignCompact(wif.PrivKey, 3574 messageHash, wif.CompressPubKey) 3575 if err != nil { 3576 return nil, &btcjson.RPCError{ 3577 Code: btcjson.ErrRPCInvalidAddressOrKey, 3578 Message: "Sign failed", 3579 } 3580 } 3581 3582 return base64.StdEncoding.EncodeToString(sig), nil 3583 } 3584 3585 // handleStop implements the stop command. 3586 func handleStop(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 3587 select { 3588 case s.requestProcessShutdown <- struct{}{}: 3589 default: 3590 } 3591 return "btcd stopping.", nil 3592 } 3593 3594 // handleSubmitBlock implements the submitblock command. 3595 func handleSubmitBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 3596 c := cmd.(*btcjson.SubmitBlockCmd) 3597 3598 // Deserialize the submitted block. 3599 hexStr := c.HexBlock 3600 if len(hexStr)%2 != 0 { 3601 hexStr = "0" + c.HexBlock 3602 } 3603 serializedBlock, err := hex.DecodeString(hexStr) 3604 if err != nil { 3605 return nil, rpcDecodeHexError(hexStr) 3606 } 3607 3608 block, err := btcutil.NewBlockFromBytes(serializedBlock) 3609 if err != nil { 3610 return nil, &btcjson.RPCError{ 3611 Code: btcjson.ErrRPCDeserialization, 3612 Message: "Block decode failed: " + err.Error(), 3613 } 3614 } 3615 3616 // Process this block using the same rules as blocks coming from other 3617 // nodes. This will in turn relay it to the network like normal. 3618 _, err = s.cfg.SyncMgr.SubmitBlock(block, blockchain.BFNone) 3619 if err != nil { 3620 return fmt.Sprintf("rejected: %s", err.Error()), nil 3621 } 3622 3623 rpcsLog.Infof("Accepted block %s via submitblock", block.Hash()) 3624 return nil, nil 3625 } 3626 3627 // handleUptime implements the uptime command. 3628 func handleUptime(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 3629 return time.Now().Unix() - s.cfg.StartupTime, nil 3630 } 3631 3632 // handleValidateAddress implements the validateaddress command. 3633 func handleValidateAddress(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 3634 c := cmd.(*btcjson.ValidateAddressCmd) 3635 3636 result := btcjson.ValidateAddressChainResult{} 3637 addr, err := btcutil.DecodeAddress(c.Address, s.cfg.ChainParams) 3638 if err != nil { 3639 // Return the default value (false) for IsValid. 3640 return result, nil 3641 } 3642 3643 switch addr := addr.(type) { 3644 case *btcutil.AddressPubKeyHash: 3645 result.IsScript = btcjson.Bool(false) 3646 result.IsWitness = btcjson.Bool(false) 3647 3648 case *btcutil.AddressScriptHash: 3649 result.IsScript = btcjson.Bool(true) 3650 result.IsWitness = btcjson.Bool(false) 3651 3652 case *btcutil.AddressPubKey: 3653 result.IsScript = btcjson.Bool(false) 3654 result.IsWitness = btcjson.Bool(false) 3655 3656 case *btcutil.AddressWitnessPubKeyHash: 3657 result.IsScript = btcjson.Bool(false) 3658 result.IsWitness = btcjson.Bool(true) 3659 result.WitnessVersion = btcjson.Int32(int32(addr.WitnessVersion())) 3660 result.WitnessProgram = btcjson.String(hex.EncodeToString(addr.WitnessProgram())) 3661 3662 case *btcutil.AddressWitnessScriptHash: 3663 result.IsScript = btcjson.Bool(true) 3664 result.IsWitness = btcjson.Bool(true) 3665 result.WitnessVersion = btcjson.Int32(int32(addr.WitnessVersion())) 3666 result.WitnessProgram = btcjson.String(hex.EncodeToString(addr.WitnessProgram())) 3667 3668 default: 3669 // Handle the case when a new Address is supported by btcutil, but none 3670 // of the cases were matched in the switch block. The current behaviour 3671 // is to do nothing, and only populate the Address and IsValid fields. 3672 } 3673 3674 result.Address = addr.EncodeAddress() 3675 result.IsValid = true 3676 3677 return result, nil 3678 } 3679 3680 func verifyChain(s *rpcServer, level, depth int32) error { 3681 best := s.cfg.Chain.BestSnapshot() 3682 finishHeight := best.Height - depth 3683 if finishHeight < 0 { 3684 finishHeight = 0 3685 } 3686 rpcsLog.Infof("Verifying chain for %d blocks at level %d", 3687 best.Height-finishHeight, level) 3688 3689 for height := best.Height; height > finishHeight; height-- { 3690 // Level 0 just looks up the block. 3691 block, err := s.cfg.Chain.BlockByHeight(height) 3692 if err != nil { 3693 rpcsLog.Errorf("Verify is unable to fetch block at "+ 3694 "height %d: %v", height, err) 3695 return err 3696 } 3697 3698 // Level 1 does basic chain sanity checks. 3699 if level > 0 { 3700 err := blockchain.CheckBlockSanity(block, 3701 s.cfg.ChainParams.PowLimit, s.cfg.TimeSource) 3702 if err != nil { 3703 rpcsLog.Errorf("Verify is unable to validate "+ 3704 "block at hash %v height %d: %v", 3705 block.Hash(), height, err) 3706 return err 3707 } 3708 } 3709 } 3710 rpcsLog.Infof("Chain verify completed successfully") 3711 3712 return nil 3713 } 3714 3715 // handleVerifyChain implements the verifychain command. 3716 func handleVerifyChain(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 3717 c := cmd.(*btcjson.VerifyChainCmd) 3718 3719 var checkLevel, checkDepth int32 3720 if c.CheckLevel != nil { 3721 checkLevel = *c.CheckLevel 3722 } 3723 if c.CheckDepth != nil { 3724 checkDepth = *c.CheckDepth 3725 } 3726 3727 err := verifyChain(s, checkLevel, checkDepth) 3728 return err == nil, nil 3729 } 3730 3731 // handleVerifyMessage implements the verifymessage command. 3732 func handleVerifyMessage(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 3733 c := cmd.(*btcjson.VerifyMessageCmd) 3734 3735 // Decode the provided address. 3736 params := s.cfg.ChainParams 3737 addr, err := btcutil.DecodeAddress(c.Address, params) 3738 if err != nil { 3739 return nil, &btcjson.RPCError{ 3740 Code: btcjson.ErrRPCInvalidAddressOrKey, 3741 Message: "Invalid address or key: " + err.Error(), 3742 } 3743 } 3744 3745 // Only P2PKH addresses are valid for signing. 3746 if _, ok := addr.(*btcutil.AddressPubKeyHash); !ok { 3747 return nil, &btcjson.RPCError{ 3748 Code: btcjson.ErrRPCType, 3749 Message: "Address is not a pay-to-pubkey-hash address", 3750 } 3751 } 3752 3753 // Decode base64 signature. 3754 sig, err := base64.StdEncoding.DecodeString(c.Signature) 3755 if err != nil { 3756 return nil, &btcjson.RPCError{ 3757 Code: btcjson.ErrRPCParse.Code, 3758 Message: "Malformed base64 encoding: " + err.Error(), 3759 } 3760 } 3761 3762 // Validate the signature - this just shows that it was valid at all. 3763 // we will compare it with the key next. 3764 var buf bytes.Buffer 3765 wire.WriteVarString(&buf, 0, messageSignatureHeader) 3766 wire.WriteVarString(&buf, 0, c.Message) 3767 expectedMessageHash := chainhash.DoubleHashB(buf.Bytes()) 3768 pk, wasCompressed, err := ecdsa.RecoverCompact(sig, 3769 expectedMessageHash) 3770 if err != nil { 3771 // Mirror Bitcoin Core behavior, which treats error in 3772 // RecoverCompact as invalid signature. 3773 return false, nil 3774 } 3775 3776 // Reconstruct the pubkey hash. 3777 var serializedPK []byte 3778 if wasCompressed { 3779 serializedPK = pk.SerializeCompressed() 3780 } else { 3781 serializedPK = pk.SerializeUncompressed() 3782 } 3783 address, err := btcutil.NewAddressPubKey(serializedPK, params) 3784 if err != nil { 3785 // Again mirror Bitcoin Core behavior, which treats error in public key 3786 // reconstruction as invalid signature. 3787 return false, nil 3788 } 3789 3790 // Return boolean if addresses match. 3791 return address.EncodeAddress() == c.Address, nil 3792 } 3793 3794 // handleVersion implements the version command. 3795 // 3796 // NOTE: This is a btcsuite extension ported from github.com/decred/dcrd. 3797 func handleVersion(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { 3798 result := map[string]btcjson.VersionResult{ 3799 "btcdjsonrpcapi": { 3800 VersionString: jsonrpcSemverString, 3801 Major: jsonrpcSemverMajor, 3802 Minor: jsonrpcSemverMinor, 3803 Patch: jsonrpcSemverPatch, 3804 }, 3805 } 3806 return result, nil 3807 } 3808 3809 // rpcServer provides a concurrent safe RPC server to a chain server. 3810 type rpcServer struct { 3811 started int32 3812 shutdown int32 3813 cfg rpcserverConfig 3814 authsha [sha256.Size]byte 3815 limitauthsha [sha256.Size]byte 3816 ntfnMgr *wsNotificationManager 3817 numClients int32 3818 statusLines map[int]string 3819 statusLock sync.RWMutex 3820 wg sync.WaitGroup 3821 gbtWorkState *gbtWorkState 3822 helpCacher *helpCacher 3823 requestProcessShutdown chan struct{} 3824 quit chan int 3825 } 3826 3827 // httpStatusLine returns a response Status-Line (RFC 2616 Section 6.1) 3828 // for the given request and response status code. This function was lifted and 3829 // adapted from the standard library HTTP server code since it's not exported. 3830 func (s *rpcServer) httpStatusLine(req *http.Request, code int) string { 3831 // Fast path: 3832 key := code 3833 proto11 := req.ProtoAtLeast(1, 1) 3834 if !proto11 { 3835 key = -key 3836 } 3837 s.statusLock.RLock() 3838 line, ok := s.statusLines[key] 3839 s.statusLock.RUnlock() 3840 if ok { 3841 return line 3842 } 3843 3844 // Slow path: 3845 proto := "HTTP/1.0" 3846 if proto11 { 3847 proto = "HTTP/1.1" 3848 } 3849 codeStr := strconv.Itoa(code) 3850 text := http.StatusText(code) 3851 if text != "" { 3852 line = proto + " " + codeStr + " " + text + "\r\n" 3853 s.statusLock.Lock() 3854 s.statusLines[key] = line 3855 s.statusLock.Unlock() 3856 } else { 3857 text = "status code " + codeStr 3858 line = proto + " " + codeStr + " " + text + "\r\n" 3859 } 3860 3861 return line 3862 } 3863 3864 // writeHTTPResponseHeaders writes the necessary response headers prior to 3865 // writing an HTTP body given a request to use for protocol negotiation, headers 3866 // to write, a status code, and a writer. 3867 func (s *rpcServer) writeHTTPResponseHeaders(req *http.Request, headers http.Header, code int, w io.Writer) error { 3868 _, err := io.WriteString(w, s.httpStatusLine(req, code)) 3869 if err != nil { 3870 return err 3871 } 3872 3873 err = headers.Write(w) 3874 if err != nil { 3875 return err 3876 } 3877 3878 _, err = io.WriteString(w, "\r\n") 3879 return err 3880 } 3881 3882 // Stop is used by server.go to stop the rpc listener. 3883 func (s *rpcServer) Stop() error { 3884 if atomic.AddInt32(&s.shutdown, 1) != 1 { 3885 rpcsLog.Infof("RPC server is already in the process of shutting down") 3886 return nil 3887 } 3888 rpcsLog.Warnf("RPC server shutting down") 3889 for _, listener := range s.cfg.Listeners { 3890 err := listener.Close() 3891 if err != nil { 3892 rpcsLog.Errorf("Problem shutting down rpc: %v", err) 3893 return err 3894 } 3895 } 3896 s.ntfnMgr.Shutdown() 3897 s.ntfnMgr.WaitForShutdown() 3898 close(s.quit) 3899 s.wg.Wait() 3900 rpcsLog.Infof("RPC server shutdown complete") 3901 return nil 3902 } 3903 3904 // RequestedProcessShutdown returns a channel that is sent to when an authorized 3905 // RPC client requests the process to shutdown. If the request can not be read 3906 // immediately, it is dropped. 3907 func (s *rpcServer) RequestedProcessShutdown() <-chan struct{} { 3908 return s.requestProcessShutdown 3909 } 3910 3911 // NotifyNewTransactions notifies both websocket and getblocktemplate long 3912 // poll clients of the passed transactions. This function should be called 3913 // whenever new transactions are added to the mempool. 3914 func (s *rpcServer) NotifyNewTransactions(txns []*mempool.TxDesc) { 3915 for _, txD := range txns { 3916 // Notify websocket clients about mempool transactions. 3917 s.ntfnMgr.NotifyMempoolTx(txD.Tx, true) 3918 3919 // Potentially notify any getblocktemplate long poll clients 3920 // about stale block templates due to the new transaction. 3921 s.gbtWorkState.NotifyMempoolTx(s.cfg.TxMemPool.LastUpdated()) 3922 } 3923 } 3924 3925 // limitConnections responds with a 503 service unavailable and returns true if 3926 // adding another client would exceed the maximum allow RPC clients. 3927 // 3928 // This function is safe for concurrent access. 3929 func (s *rpcServer) limitConnections(w http.ResponseWriter, remoteAddr string) bool { 3930 if int(atomic.LoadInt32(&s.numClients)+1) > cfg.RPCMaxClients { 3931 rpcsLog.Infof("Max RPC clients exceeded [%d] - "+ 3932 "disconnecting client %s", cfg.RPCMaxClients, 3933 remoteAddr) 3934 http.Error(w, "503 Too busy. Try again later.", 3935 http.StatusServiceUnavailable) 3936 return true 3937 } 3938 return false 3939 } 3940 3941 // incrementClients adds one to the number of connected RPC clients. Note 3942 // this only applies to standard clients. Websocket clients have their own 3943 // limits and are tracked separately. 3944 // 3945 // This function is safe for concurrent access. 3946 func (s *rpcServer) incrementClients() { 3947 atomic.AddInt32(&s.numClients, 1) 3948 } 3949 3950 // decrementClients subtracts one from the number of connected RPC clients. 3951 // Note this only applies to standard clients. Websocket clients have their own 3952 // limits and are tracked separately. 3953 // 3954 // This function is safe for concurrent access. 3955 func (s *rpcServer) decrementClients() { 3956 atomic.AddInt32(&s.numClients, -1) 3957 } 3958 3959 // checkAuth checks the HTTP Basic authentication supplied by a wallet 3960 // or RPC client in the HTTP request r. If the supplied authentication 3961 // does not match the username and password expected, a non-nil error is 3962 // returned. 3963 // 3964 // This check is time-constant. 3965 // 3966 // The first bool return value signifies auth success (true if successful) and 3967 // the second bool return value specifies whether the user can change the state 3968 // of the server (true) or whether the user is limited (false). The second is 3969 // always false if the first is. 3970 func (s *rpcServer) checkAuth(r *http.Request, require bool) (bool, bool, error) { 3971 authhdr := r.Header["Authorization"] 3972 if len(authhdr) <= 0 { 3973 if require { 3974 rpcsLog.Warnf("RPC authentication failure from %s", 3975 r.RemoteAddr) 3976 return false, false, errors.New("auth failure") 3977 } 3978 3979 return false, false, nil 3980 } 3981 3982 authsha := sha256.Sum256([]byte(authhdr[0])) 3983 3984 // Check for limited auth first as in environments with limited users, those 3985 // are probably expected to have a higher volume of calls 3986 limitcmp := subtle.ConstantTimeCompare(authsha[:], s.limitauthsha[:]) 3987 if limitcmp == 1 { 3988 return true, false, nil 3989 } 3990 3991 // Check for admin-level auth 3992 cmp := subtle.ConstantTimeCompare(authsha[:], s.authsha[:]) 3993 if cmp == 1 { 3994 return true, true, nil 3995 } 3996 3997 // Request's auth doesn't match either user 3998 rpcsLog.Warnf("RPC authentication failure from %s", r.RemoteAddr) 3999 return false, false, errors.New("auth failure") 4000 } 4001 4002 // parsedRPCCmd represents a JSON-RPC request object that has been parsed into 4003 // a known concrete command along with any error that might have happened while 4004 // parsing it. 4005 type parsedRPCCmd struct { 4006 jsonrpc btcjson.RPCVersion 4007 id interface{} 4008 method string 4009 cmd interface{} 4010 err *btcjson.RPCError 4011 } 4012 4013 // standardCmdResult checks that a parsed command is a standard Bitcoin JSON-RPC 4014 // command and runs the appropriate handler to reply to the command. Any 4015 // commands which are not recognized or not implemented will return an error 4016 // suitable for use in replies. 4017 func (s *rpcServer) standardCmdResult(cmd *parsedRPCCmd, closeChan <-chan struct{}) (interface{}, error) { 4018 handler, ok := rpcHandlers[cmd.method] 4019 if ok { 4020 goto handled 4021 } 4022 _, ok = rpcAskWallet[cmd.method] 4023 if ok { 4024 handler = handleAskWallet 4025 goto handled 4026 } 4027 _, ok = rpcUnimplemented[cmd.method] 4028 if ok { 4029 handler = handleUnimplemented 4030 goto handled 4031 } 4032 return nil, btcjson.ErrRPCMethodNotFound 4033 handled: 4034 4035 return handler(s, cmd.cmd, closeChan) 4036 } 4037 4038 // parseCmd parses a JSON-RPC request object into known concrete command. The 4039 // err field of the returned parsedRPCCmd struct will contain an RPC error that 4040 // is suitable for use in replies if the command is invalid in some way such as 4041 // an unregistered command or invalid parameters. 4042 func parseCmd(request *btcjson.Request) *parsedRPCCmd { 4043 parsedCmd := parsedRPCCmd{ 4044 jsonrpc: request.Jsonrpc, 4045 id: request.ID, 4046 method: request.Method, 4047 } 4048 4049 cmd, err := btcjson.UnmarshalCmd(request) 4050 if err != nil { 4051 // When the error is because the method is not registered, 4052 // produce a method not found RPC error. 4053 if jerr, ok := err.(btcjson.Error); ok && 4054 jerr.ErrorCode == btcjson.ErrUnregisteredMethod { 4055 4056 parsedCmd.err = btcjson.ErrRPCMethodNotFound 4057 return &parsedCmd 4058 } 4059 4060 // Otherwise, some type of invalid parameters is the 4061 // cause, so produce the equivalent RPC error. 4062 parsedCmd.err = btcjson.NewRPCError( 4063 btcjson.ErrRPCInvalidParams.Code, err.Error()) 4064 return &parsedCmd 4065 } 4066 4067 parsedCmd.cmd = cmd 4068 return &parsedCmd 4069 } 4070 4071 // createMarshalledReply returns a new marshalled JSON-RPC response given the 4072 // passed parameters. It will automatically convert errors that are not of 4073 // the type *btcjson.RPCError to the appropriate type as needed. 4074 func createMarshalledReply(rpcVersion btcjson.RPCVersion, id interface{}, result interface{}, replyErr error) ([]byte, error) { 4075 var jsonErr *btcjson.RPCError 4076 if replyErr != nil { 4077 if jErr, ok := replyErr.(*btcjson.RPCError); ok { 4078 jsonErr = jErr 4079 } else { 4080 jsonErr = internalRPCError(replyErr.Error(), "") 4081 } 4082 } 4083 4084 return btcjson.MarshalResponse(rpcVersion, id, result, jsonErr) 4085 } 4086 4087 // processRequest determines the incoming request type (single or batched), 4088 // parses it and returns a marshalled response. 4089 func (s *rpcServer) processRequest(request *btcjson.Request, isAdmin bool, closeChan <-chan struct{}) []byte { 4090 var result interface{} 4091 var err error 4092 var jsonErr *btcjson.RPCError 4093 4094 if !isAdmin { 4095 if _, ok := rpcLimited[request.Method]; !ok { 4096 jsonErr = internalRPCError("limited user not "+ 4097 "authorized for this method", "") 4098 } 4099 } 4100 4101 if jsonErr == nil { 4102 if request.Method == "" || request.Params == nil { 4103 jsonErr = &btcjson.RPCError{ 4104 Code: btcjson.ErrRPCInvalidRequest.Code, 4105 Message: "Invalid request: malformed", 4106 } 4107 msg, err := createMarshalledReply(request.Jsonrpc, request.ID, result, jsonErr) 4108 if err != nil { 4109 rpcsLog.Errorf("Failed to marshal reply: %v", err) 4110 return nil 4111 } 4112 return msg 4113 } 4114 4115 // Valid requests with no ID (notifications) must not have a response 4116 // per the JSON-RPC spec. 4117 if request.ID == nil { 4118 return nil 4119 } 4120 4121 // Attempt to parse the JSON-RPC request into a known 4122 // concrete command. 4123 parsedCmd := parseCmd(request) 4124 if parsedCmd.err != nil { 4125 jsonErr = parsedCmd.err 4126 } else { 4127 result, err = s.standardCmdResult(parsedCmd, 4128 closeChan) 4129 if err != nil { 4130 if rpcErr, ok := err.(*btcjson.RPCError); ok { 4131 jsonErr = rpcErr 4132 } else { 4133 jsonErr = &btcjson.RPCError{ 4134 Code: btcjson.ErrRPCInvalidRequest.Code, 4135 Message: "Invalid request: malformed", 4136 } 4137 } 4138 } 4139 } 4140 } 4141 4142 // Marshal the response. 4143 msg, err := createMarshalledReply(request.Jsonrpc, request.ID, result, jsonErr) 4144 if err != nil { 4145 rpcsLog.Errorf("Failed to marshal reply: %v", err) 4146 return nil 4147 } 4148 return msg 4149 } 4150 4151 // jsonRPCRead handles reading and responding to RPC messages. 4152 func (s *rpcServer) jsonRPCRead(w http.ResponseWriter, r *http.Request, isAdmin bool) { 4153 if atomic.LoadInt32(&s.shutdown) != 0 { 4154 return 4155 } 4156 4157 // Read and close the JSON-RPC request body from the caller. 4158 body, err := ioutil.ReadAll(r.Body) 4159 r.Body.Close() 4160 if err != nil { 4161 errCode := http.StatusBadRequest 4162 http.Error(w, fmt.Sprintf("%d error reading JSON message: %v", 4163 errCode, err), errCode) 4164 return 4165 } 4166 4167 // Unfortunately, the http server doesn't provide the ability to 4168 // change the read deadline for the new connection and having one breaks 4169 // long polling. However, not having a read deadline on the initial 4170 // connection would mean clients can connect and idle forever. Thus, 4171 // hijack the connecton from the HTTP server, clear the read deadline, 4172 // and handle writing the response manually. 4173 hj, ok := w.(http.Hijacker) 4174 if !ok { 4175 errMsg := "webserver doesn't support hijacking" 4176 rpcsLog.Warnf(errMsg) 4177 errCode := http.StatusInternalServerError 4178 http.Error(w, strconv.Itoa(errCode)+" "+errMsg, errCode) 4179 return 4180 } 4181 conn, buf, err := hj.Hijack() 4182 if err != nil { 4183 rpcsLog.Warnf("Failed to hijack HTTP connection: %v", err) 4184 errCode := http.StatusInternalServerError 4185 http.Error(w, strconv.Itoa(errCode)+" "+err.Error(), errCode) 4186 return 4187 } 4188 defer conn.Close() 4189 defer buf.Flush() 4190 conn.SetReadDeadline(timeZeroVal) 4191 4192 // Attempt to parse the raw body into a JSON-RPC request. 4193 // Setup a close notifier. Since the connection is hijacked, 4194 // the CloseNotifer on the ResponseWriter is not available. 4195 closeChan := make(chan struct{}, 1) 4196 go func() { 4197 _, err = conn.Read(make([]byte, 1)) 4198 if err != nil { 4199 close(closeChan) 4200 } 4201 }() 4202 4203 var results []json.RawMessage 4204 var batchSize int 4205 var batchedRequest bool 4206 4207 // Determine request type 4208 if bytes.HasPrefix(body, batchedRequestPrefix) { 4209 batchedRequest = true 4210 } 4211 4212 // Process a single request 4213 if !batchedRequest { 4214 var req btcjson.Request 4215 var resp json.RawMessage 4216 err = json.Unmarshal(body, &req) 4217 if err != nil { 4218 jsonErr := &btcjson.RPCError{ 4219 Code: btcjson.ErrRPCParse.Code, 4220 Message: fmt.Sprintf("Failed to parse request: %v", 4221 err), 4222 } 4223 resp, err = btcjson.MarshalResponse(btcjson.RpcVersion1, nil, nil, jsonErr) 4224 if err != nil { 4225 rpcsLog.Errorf("Failed to create reply: %v", err) 4226 } 4227 } 4228 4229 if err == nil { 4230 // The JSON-RPC 1.0 spec defines that notifications must have their "id" 4231 // set to null and states that notifications do not have a response. 4232 // 4233 // A JSON-RPC 2.0 notification is a request with "json-rpc":"2.0", and 4234 // without an "id" member. The specification states that notifications 4235 // must not be responded to. JSON-RPC 2.0 permits the null value as a 4236 // valid request id, therefore such requests are not notifications. 4237 // 4238 // Bitcoin Core serves requests with "id":null or even an absent "id", 4239 // and responds to such requests with "id":null in the response. 4240 // 4241 // Btcd does not respond to any request without and "id" or "id":null, 4242 // regardless the indicated JSON-RPC protocol version unless RPC quirks 4243 // are enabled. With RPC quirks enabled, such requests will be responded 4244 // to if the reqeust does not indicate JSON-RPC version. 4245 // 4246 // RPC quirks can be enabled by the user to avoid compatibility issues 4247 // with software relying on Core's behavior. 4248 if req.ID == nil && !(cfg.RPCQuirks && req.Jsonrpc == "") { 4249 return 4250 } 4251 resp = s.processRequest(&req, isAdmin, closeChan) 4252 } 4253 4254 if resp != nil { 4255 results = append(results, resp) 4256 } 4257 } 4258 4259 // Process a batched request 4260 if batchedRequest { 4261 var batchedRequests []interface{} 4262 var resp json.RawMessage 4263 err = json.Unmarshal(body, &batchedRequests) 4264 if err != nil { 4265 jsonErr := &btcjson.RPCError{ 4266 Code: btcjson.ErrRPCParse.Code, 4267 Message: fmt.Sprintf("Failed to parse request: %v", 4268 err), 4269 } 4270 resp, err = btcjson.MarshalResponse(btcjson.RpcVersion2, nil, nil, jsonErr) 4271 if err != nil { 4272 rpcsLog.Errorf("Failed to create reply: %v", err) 4273 } 4274 4275 if resp != nil { 4276 results = append(results, resp) 4277 } 4278 } 4279 4280 if err == nil { 4281 // Response with an empty batch error if the batch size is zero 4282 if len(batchedRequests) == 0 { 4283 jsonErr := &btcjson.RPCError{ 4284 Code: btcjson.ErrRPCInvalidRequest.Code, 4285 Message: "Invalid request: empty batch", 4286 } 4287 resp, err = btcjson.MarshalResponse(btcjson.RpcVersion2, nil, nil, jsonErr) 4288 if err != nil { 4289 rpcsLog.Errorf("Failed to marshal reply: %v", err) 4290 } 4291 4292 if resp != nil { 4293 results = append(results, resp) 4294 } 4295 } 4296 4297 // Process each batch entry individually 4298 if len(batchedRequests) > 0 { 4299 batchSize = len(batchedRequests) 4300 4301 for _, entry := range batchedRequests { 4302 var reqBytes []byte 4303 reqBytes, err = json.Marshal(entry) 4304 if err != nil { 4305 jsonErr := &btcjson.RPCError{ 4306 Code: btcjson.ErrRPCInvalidRequest.Code, 4307 Message: fmt.Sprintf("Invalid request: %v", 4308 err), 4309 } 4310 resp, err = btcjson.MarshalResponse(btcjson.RpcVersion2, nil, nil, jsonErr) 4311 if err != nil { 4312 rpcsLog.Errorf("Failed to create reply: %v", err) 4313 } 4314 4315 if resp != nil { 4316 results = append(results, resp) 4317 } 4318 continue 4319 } 4320 4321 var req btcjson.Request 4322 err := json.Unmarshal(reqBytes, &req) 4323 if err != nil { 4324 jsonErr := &btcjson.RPCError{ 4325 Code: btcjson.ErrRPCInvalidRequest.Code, 4326 Message: fmt.Sprintf("Invalid request: %v", 4327 err), 4328 } 4329 resp, err = btcjson.MarshalResponse("", nil, nil, jsonErr) 4330 if err != nil { 4331 rpcsLog.Errorf("Failed to create reply: %v", err) 4332 } 4333 4334 if resp != nil { 4335 results = append(results, resp) 4336 } 4337 continue 4338 } 4339 4340 resp = s.processRequest(&req, isAdmin, closeChan) 4341 if resp != nil { 4342 results = append(results, resp) 4343 } 4344 } 4345 } 4346 } 4347 } 4348 4349 var msg = []byte{} 4350 if batchedRequest && batchSize > 0 { 4351 if len(results) > 0 { 4352 // Form the batched response json 4353 var buffer bytes.Buffer 4354 buffer.WriteByte('[') 4355 for idx, reply := range results { 4356 if idx == len(results)-1 { 4357 buffer.Write(reply) 4358 buffer.WriteByte(']') 4359 break 4360 } 4361 buffer.Write(reply) 4362 buffer.WriteByte(',') 4363 } 4364 msg = buffer.Bytes() 4365 } 4366 } 4367 4368 if !batchedRequest || batchSize == 0 { 4369 // Respond with the first results entry for single requests 4370 if len(results) > 0 { 4371 msg = results[0] 4372 } 4373 } 4374 4375 // Write the response. 4376 err = s.writeHTTPResponseHeaders(r, w.Header(), http.StatusOK, buf) 4377 if err != nil { 4378 rpcsLog.Error(err) 4379 return 4380 } 4381 if _, err := buf.Write(msg); err != nil { 4382 rpcsLog.Errorf("Failed to write marshalled reply: %v", err) 4383 } 4384 4385 // Terminate with newline to maintain compatibility with Bitcoin Core. 4386 if err := buf.WriteByte('\n'); err != nil { 4387 rpcsLog.Errorf("Failed to append terminating newline to reply: %v", err) 4388 } 4389 } 4390 4391 // jsonAuthFail sends a message back to the client if the http auth is rejected. 4392 func jsonAuthFail(w http.ResponseWriter) { 4393 w.Header().Add("WWW-Authenticate", `Basic realm="btcd RPC"`) 4394 http.Error(w, "401 Unauthorized.", http.StatusUnauthorized) 4395 } 4396 4397 // Start is used by server.go to start the rpc listener. 4398 func (s *rpcServer) Start() { 4399 if atomic.AddInt32(&s.started, 1) != 1 { 4400 return 4401 } 4402 4403 rpcsLog.Trace("Starting RPC server") 4404 rpcServeMux := http.NewServeMux() 4405 httpServer := &http.Server{ 4406 Handler: rpcServeMux, 4407 4408 // Timeout connections which don't complete the initial 4409 // handshake within the allowed timeframe. 4410 ReadTimeout: time.Second * rpcAuthTimeoutSeconds, 4411 } 4412 rpcServeMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 4413 w.Header().Set("Connection", "close") 4414 w.Header().Set("Content-Type", "application/json") 4415 r.Close = true 4416 4417 // Limit the number of connections to max allowed. 4418 if s.limitConnections(w, r.RemoteAddr) { 4419 return 4420 } 4421 4422 // Keep track of the number of connected clients. 4423 s.incrementClients() 4424 defer s.decrementClients() 4425 _, isAdmin, err := s.checkAuth(r, true) 4426 if err != nil { 4427 jsonAuthFail(w) 4428 return 4429 } 4430 4431 // Read and respond to the request. 4432 s.jsonRPCRead(w, r, isAdmin) 4433 }) 4434 4435 // Websocket endpoint. 4436 rpcServeMux.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { 4437 authenticated, isAdmin, err := s.checkAuth(r, false) 4438 if err != nil { 4439 jsonAuthFail(w) 4440 return 4441 } 4442 4443 // Attempt to upgrade the connection to a websocket connection 4444 // using the default size for read/write buffers. 4445 ws, err := websocket.Upgrade(w, r, nil, 0, 0) 4446 if err != nil { 4447 if _, ok := err.(websocket.HandshakeError); !ok { 4448 rpcsLog.Errorf("Unexpected websocket error: %v", 4449 err) 4450 } 4451 http.Error(w, "400 Bad Request.", http.StatusBadRequest) 4452 return 4453 } 4454 s.WebsocketHandler(ws, r.RemoteAddr, authenticated, isAdmin) 4455 }) 4456 4457 for _, listener := range s.cfg.Listeners { 4458 s.wg.Add(1) 4459 go func(listener net.Listener) { 4460 rpcsLog.Infof("RPC server listening on %s", listener.Addr()) 4461 httpServer.Serve(listener) 4462 rpcsLog.Tracef("RPC listener done for %s", listener.Addr()) 4463 s.wg.Done() 4464 }(listener) 4465 } 4466 4467 s.ntfnMgr.Start() 4468 } 4469 4470 // genCertPair generates a key/cert pair to the paths provided. 4471 func genCertPair(certFile, keyFile string) error { 4472 rpcsLog.Infof("Generating TLS certificates...") 4473 4474 org := "btcd autogenerated cert" 4475 validUntil := time.Now().Add(10 * 365 * 24 * time.Hour) 4476 cert, key, err := btcutil.NewTLSCertPair(org, validUntil, nil) 4477 if err != nil { 4478 return err 4479 } 4480 4481 // Write cert and key files. 4482 if err = ioutil.WriteFile(certFile, cert, 0666); err != nil { 4483 return err 4484 } 4485 if err = ioutil.WriteFile(keyFile, key, 0600); err != nil { 4486 os.Remove(certFile) 4487 return err 4488 } 4489 4490 rpcsLog.Infof("Done generating TLS certificates") 4491 return nil 4492 } 4493 4494 // rpcserverPeer represents a peer for use with the RPC server. 4495 // 4496 // The interface contract requires that all of these methods are safe for 4497 // concurrent access. 4498 type rpcserverPeer interface { 4499 // ToPeer returns the underlying peer instance. 4500 ToPeer() *peer.Peer 4501 4502 // IsTxRelayDisabled returns whether or not the peer has disabled 4503 // transaction relay. 4504 IsTxRelayDisabled() bool 4505 4506 // BanScore returns the current integer value that represents how close 4507 // the peer is to being banned. 4508 BanScore() uint32 4509 4510 // FeeFilter returns the requested current minimum fee rate for which 4511 // transactions should be announced. 4512 FeeFilter() int64 4513 } 4514 4515 // rpcserverConnManager represents a connection manager for use with the RPC 4516 // server. 4517 // 4518 // The interface contract requires that all of these methods are safe for 4519 // concurrent access. 4520 type rpcserverConnManager interface { 4521 // Connect adds the provided address as a new outbound peer. The 4522 // permanent flag indicates whether or not to make the peer persistent 4523 // and reconnect if the connection is lost. Attempting to connect to an 4524 // already existing peer will return an error. 4525 Connect(addr string, permanent bool) error 4526 4527 // RemoveByID removes the peer associated with the provided id from the 4528 // list of persistent peers. Attempting to remove an id that does not 4529 // exist will return an error. 4530 RemoveByID(id int32) error 4531 4532 // RemoveByAddr removes the peer associated with the provided address 4533 // from the list of persistent peers. Attempting to remove an address 4534 // that does not exist will return an error. 4535 RemoveByAddr(addr string) error 4536 4537 // DisconnectByID disconnects the peer associated with the provided id. 4538 // This applies to both inbound and outbound peers. Attempting to 4539 // remove an id that does not exist will return an error. 4540 DisconnectByID(id int32) error 4541 4542 // DisconnectByAddr disconnects the peer associated with the provided 4543 // address. This applies to both inbound and outbound peers. 4544 // Attempting to remove an address that does not exist will return an 4545 // error. 4546 DisconnectByAddr(addr string) error 4547 4548 // ConnectedCount returns the number of currently connected peers. 4549 ConnectedCount() int32 4550 4551 // NetTotals returns the sum of all bytes received and sent across the 4552 // network for all peers. 4553 NetTotals() (uint64, uint64) 4554 4555 // ConnectedPeers returns an array consisting of all connected peers. 4556 ConnectedPeers() []rpcserverPeer 4557 4558 // PersistentPeers returns an array consisting of all the persistent 4559 // peers. 4560 PersistentPeers() []rpcserverPeer 4561 4562 // BroadcastMessage sends the provided message to all currently 4563 // connected peers. 4564 BroadcastMessage(msg wire.Message) 4565 4566 // AddRebroadcastInventory adds the provided inventory to the list of 4567 // inventories to be rebroadcast at random intervals until they show up 4568 // in a block. 4569 AddRebroadcastInventory(iv *wire.InvVect, data interface{}) 4570 4571 // RelayTransactions generates and relays inventory vectors for all of 4572 // the passed transactions to all connected peers. 4573 RelayTransactions(txns []*mempool.TxDesc) 4574 4575 // NodeAddresses returns an array consisting node addresses which can 4576 // potentially be used to find new nodes in the network. 4577 NodeAddresses() []*wire.NetAddressV2 4578 } 4579 4580 // rpcserverSyncManager represents a sync manager for use with the RPC server. 4581 // 4582 // The interface contract requires that all of these methods are safe for 4583 // concurrent access. 4584 type rpcserverSyncManager interface { 4585 // IsCurrent returns whether or not the sync manager believes the chain 4586 // is current as compared to the rest of the network. 4587 IsCurrent() bool 4588 4589 // SubmitBlock submits the provided block to the network after 4590 // processing it locally. 4591 SubmitBlock(block *btcutil.Block, flags blockchain.BehaviorFlags) (bool, error) 4592 4593 // Pause pauses the sync manager until the returned channel is closed. 4594 Pause() chan<- struct{} 4595 4596 // SyncPeerID returns the ID of the peer that is currently the peer being 4597 // used to sync from or 0 if there is none. 4598 SyncPeerID() int32 4599 4600 // LocateHeaders returns the headers of the blocks after the first known 4601 // block in the provided locators until the provided stop hash or the 4602 // current tip is reached, up to a max of wire.MaxBlockHeadersPerMsg 4603 // hashes. 4604 LocateHeaders(locators []*chainhash.Hash, hashStop *chainhash.Hash) []wire.BlockHeader 4605 } 4606 4607 // rpcserverConfig is a descriptor containing the RPC server configuration. 4608 type rpcserverConfig struct { 4609 // Listeners defines a slice of listeners for which the RPC server will 4610 // take ownership of and accept connections. Since the RPC server takes 4611 // ownership of these listeners, they will be closed when the RPC server 4612 // is stopped. 4613 Listeners []net.Listener 4614 4615 // StartupTime is the unix timestamp for when the server that is hosting 4616 // the RPC server started. 4617 StartupTime int64 4618 4619 // ConnMgr defines the connection manager for the RPC server to use. It 4620 // provides the RPC server with a means to do things such as add, 4621 // remove, connect, disconnect, and query peers as well as other 4622 // connection-related data and tasks. 4623 ConnMgr rpcserverConnManager 4624 4625 // SyncMgr defines the sync manager for the RPC server to use. 4626 SyncMgr rpcserverSyncManager 4627 4628 // These fields allow the RPC server to interface with the local block 4629 // chain data and state. 4630 TimeSource blockchain.MedianTimeSource 4631 Chain *blockchain.BlockChain 4632 ChainParams *chaincfg.Params 4633 DB database.DB 4634 4635 // TxMemPool defines the transaction memory pool to interact with. 4636 TxMemPool *mempool.TxPool 4637 4638 // These fields allow the RPC server to interface with mining. 4639 // 4640 // Generator produces block templates and the CPUMiner solves them using 4641 // the CPU. CPU mining is typically only useful for test purposes when 4642 // doing regression or simulation testing. 4643 Generator *mining.BlkTmplGenerator 4644 CPUMiner *cpuminer.CPUMiner 4645 4646 // These fields define any optional indexes the RPC server can make use 4647 // of to provide additional data when queried. 4648 TxIndex *indexers.TxIndex 4649 AddrIndex *indexers.AddrIndex 4650 CfIndex *indexers.CfIndex 4651 4652 // The fee estimator keeps track of how long transactions are left in 4653 // the mempool before they are mined into blocks. 4654 FeeEstimator *mempool.FeeEstimator 4655 } 4656 4657 // newRPCServer returns a new instance of the rpcServer struct. 4658 func newRPCServer(config *rpcserverConfig) (*rpcServer, error) { 4659 rpc := rpcServer{ 4660 cfg: *config, 4661 statusLines: make(map[int]string), 4662 gbtWorkState: newGbtWorkState(config.TimeSource), 4663 helpCacher: newHelpCacher(), 4664 requestProcessShutdown: make(chan struct{}), 4665 quit: make(chan int), 4666 } 4667 if cfg.RPCUser != "" && cfg.RPCPass != "" { 4668 login := cfg.RPCUser + ":" + cfg.RPCPass 4669 auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login)) 4670 rpc.authsha = sha256.Sum256([]byte(auth)) 4671 } 4672 if cfg.RPCLimitUser != "" && cfg.RPCLimitPass != "" { 4673 login := cfg.RPCLimitUser + ":" + cfg.RPCLimitPass 4674 auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login)) 4675 rpc.limitauthsha = sha256.Sum256([]byte(auth)) 4676 } 4677 rpc.ntfnMgr = newWsNotificationManager(&rpc) 4678 rpc.cfg.Chain.Subscribe(rpc.handleBlockchainNotification) 4679 4680 return &rpc, nil 4681 } 4682 4683 // Callback for notifications from blockchain. It notifies clients that are 4684 // long polling for changes or subscribed to websockets notifications. 4685 func (s *rpcServer) handleBlockchainNotification(notification *blockchain.Notification) { 4686 switch notification.Type { 4687 case blockchain.NTBlockAccepted: 4688 block, ok := notification.Data.(*btcutil.Block) 4689 if !ok { 4690 rpcsLog.Warnf("Chain accepted notification is not a block.") 4691 break 4692 } 4693 4694 // Allow any clients performing long polling via the 4695 // getblocktemplate RPC to be notified when the new block causes 4696 // their old block template to become stale. 4697 s.gbtWorkState.NotifyBlockConnected(block.Hash()) 4698 4699 case blockchain.NTBlockConnected: 4700 block, ok := notification.Data.(*btcutil.Block) 4701 if !ok { 4702 rpcsLog.Warnf("Chain connected notification is not a block.") 4703 break 4704 } 4705 4706 // Notify registered websocket clients of incoming block. 4707 s.ntfnMgr.NotifyBlockConnected(block) 4708 4709 case blockchain.NTBlockDisconnected: 4710 block, ok := notification.Data.(*btcutil.Block) 4711 if !ok { 4712 rpcsLog.Warnf("Chain disconnected notification is not a block.") 4713 break 4714 } 4715 4716 // Notify registered websocket clients. 4717 s.ntfnMgr.NotifyBlockDisconnected(block) 4718 } 4719 } 4720 4721 func init() { 4722 rpcHandlers = rpcHandlersBeforeInit 4723 rand.Seed(time.Now().UnixNano()) 4724 }