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