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.
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"
47 // API version constants
49 jsonrpcSemverString = "1.3.0"
50 jsonrpcSemverMajor = 1
51 jsonrpcSemverMinor = 3
52 jsonrpcSemverPatch = 0
56 // rpcAuthTimeoutSeconds is the number of seconds a connection to the
57 // RPC server is allowed to stay open without authenticating before it
59 rpcAuthTimeoutSeconds = 10
61 // uint256Size is the number of bytes needed to represent an unsigned
65 // gbtNonceRange is two 32-bit big-endian hexadecimal integers which
66 // represent the valid ranges of nonces returned by the getblocktemplate
68 gbtNonceRange = "00000000ffffffff"
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
76 // maxProtocolVersion is the max protocol version the server supports.
77 maxProtocolVersion = 70002
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",
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
93 gbtCoinbaseAux = &btcjson.GetBlockTemplateResultAux{
94 Flags: hex.EncodeToString(builderScript(txscript.
96 AddData([]byte(mining.CoinbaseFlags)))),
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"}
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",
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",
123 type commandHandler func(*rpcServer, interface{}, <-chan struct{}) (interface{}, error)
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.
128 var rpcHandlers map[string]commandHandler
129 var rpcHandlersBeforeInit = map[string]commandHandler{
130 "addnode": handleAddNode,
131 "createrawtransaction": handleCreateRawTransaction,
132 "debuglevel": handleDebugLevel,
133 "decoderawtransaction": handleDecodeRawTransaction,
134 "decodescript": handleDecodeScript,
135 "generate": handleGenerate,
136 "getaddednodeinfo": handleGetAddedNodeInfo,
137 "getbestblock": handleGetBestBlock,
138 "getbestblockhash": handleGetBestBlockHash,
139 "getblock": handleGetBlock,
140 "getblockchaininfo": handleGetBlockChainInfo,
141 "getblockcount": handleGetBlockCount,
142 "getblockhash": handleGetBlockHash,
143 "getblockheader": handleGetBlockHeader,
144 "getblocktemplate": handleGetBlockTemplate,
145 "getconnectioncount": handleGetConnectionCount,
146 "getcurrentnet": handleGetCurrentNet,
147 "getdifficulty": handleGetDifficulty,
148 "getgenerate": handleGetGenerate,
149 "gethashespersec": handleGetHashesPerSec,
150 "getheaders": handleGetHeaders,
151 "getinfo": handleGetInfo,
152 "getmempoolinfo": handleGetMempoolInfo,
153 "getmininginfo": handleGetMiningInfo,
154 "getnettotals": handleGetNetTotals,
155 "getnetworkhashps": handleGetNetworkHashPS,
156 "getpeerinfo": handleGetPeerInfo,
157 "getrawmempool": handleGetRawMempool,
158 "getrawtransaction": handleGetRawTransaction,
159 "gettxout": handleGetTxOut,
163 "searchrawtransactions": handleSearchRawTransactions,
164 "sendrawtransaction": handleSendRawTransaction,
165 "setgenerate": handleSetGenerate,
167 "submitblock": handleSubmitBlock,
168 "uptime": handleUptime,
169 "validateaddress": handleValidateAddress,
170 "verifychain": handleVerifyChain,
171 "verifymessage": handleVerifyMessage,
172 "version": handleVersion,
175 // list of commands that we recognize, but for which btcd has no support because
176 // it lacks support for wallet functionality. For these commands the user
177 // should ask a connected instance of btcwallet.
178 var rpcAskWallet = map[string]struct{}{
179 "addmultisigaddress": {},
181 "createencryptedwallet": {},
182 "createmultisig": {},
187 "getaccountaddress": {},
188 "getaddressesbyaccount": {},
191 "getrawchangeaddress": {},
192 "getreceivedbyaccount": {},
193 "getreceivedbyaddress": {},
194 "gettransaction": {},
195 "gettxoutsetinfo": {},
196 "getunconfirmedbalance": {},
202 "listaddressgroupings": {},
203 "listlockunspent": {},
204 "listreceivedbyaccount": {},
205 "listreceivedbyaddress": {},
206 "listsinceblock": {},
207 "listtransactions": {},
217 "signrawtransaction": {},
219 "walletpassphrase": {},
220 "walletpassphrasechange": {},
223 // Commands that are currently unimplemented, but should ultimately be.
224 var rpcUnimplemented = map[string]struct{}{
226 "estimatepriority": {},
228 "getmempoolentry": {},
229 "getnetworkinfo": {},
231 "invalidateblock": {},
233 "reconsiderblock": {},
236 // Commands that are available to a limited user
237 var rpcLimited = map[string]struct{}{
238 // Websockets commands
241 "notifynewtransactions": {},
242 "notifyreceived": {},
248 // Websockets AND HTTP/S commands
251 // HTTP/S-only commands
252 "createrawtransaction": {},
253 "decoderawtransaction": {},
256 "getbestblockhash": {},
260 "getblockheader": {},
266 "getnetworkhashps": {},
268 "getrawtransaction": {},
270 "searchrawtransactions": {},
271 "sendrawtransaction": {},
274 "validateaddress": {},
279 // builderScript is a convenience function which is used for hard-coded scripts
280 // built with the script builder. Any errors are converted to a panic since it
281 // is only, and must only, be used with hard-coded, and therefore, known good,
283 func builderScript(builder *txscript.ScriptBuilder) []byte {
284 script, err := builder.Script()
291 // internalRPCError is a convenience function to convert an internal error to
292 // an RPC error with the appropriate code set. It also logs the error to the
293 // RPC server subsystem since internal errors really should not occur. The
294 // context parameter is only used in the log message and may be empty if it's
296 func internalRPCError(errStr, context string) *btcjson.RPCError {
299 logStr = context + ": " + errStr
301 rpcsLog.Error(logStr)
302 return btcjson.NewRPCError(btcjson.ErrRPCInternal.Code, errStr)
305 // rpcDecodeHexError is a convenience function for returning a nicely formatted
306 // RPC error which indicates the provided hex string failed to decode.
307 func rpcDecodeHexError(gotHex string) *btcjson.RPCError {
308 return btcjson.NewRPCError(btcjson.ErrRPCDecodeHexString,
309 fmt.Sprintf("Argument must be hexadecimal string (not %q)",
313 // rpcNoTxInfoError is a convenience function for returning a nicely formatted
314 // RPC error which indicates there is no information available for the provided
316 func rpcNoTxInfoError(txHash *chainhash.Hash) *btcjson.RPCError {
317 return btcjson.NewRPCError(btcjson.ErrRPCNoTxInfo,
318 fmt.Sprintf("No information available about transaction %v",
322 // gbtWorkState houses state that is used in between multiple RPC invocations to
324 type gbtWorkState struct {
326 lastTxUpdate time.Time
327 lastGenerated time.Time
328 prevHash *chainhash.Hash
329 minTimestamp time.Time
330 template *mining.BlockTemplate
331 notifyMap map[chainhash.Hash]map[int64]chan struct{}
332 timeSource blockchain.MedianTimeSource
335 // newGbtWorkState returns a new instance of a gbtWorkState with all internal
336 // fields initialized and ready to use.
337 func newGbtWorkState(timeSource blockchain.MedianTimeSource) *gbtWorkState {
338 return &gbtWorkState{
339 notifyMap: make(map[chainhash.Hash]map[int64]chan struct{}),
340 timeSource: timeSource,
344 // handleUnimplemented is the handler for commands that should ultimately be
345 // supported but are not yet implemented.
346 func handleUnimplemented(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
347 return nil, ErrRPCUnimplemented
350 // handleAskWallet is the handler for commands that are recognized as valid, but
351 // are unable to answer correctly since it involves wallet state.
352 // These commands will be implemented in btcwallet.
353 func handleAskWallet(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
354 return nil, ErrRPCNoWallet
357 // handleAddNode handles addnode commands.
358 func handleAddNode(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
359 c := cmd.(*btcjson.AddNodeCmd)
361 addr := normalizeAddress(c.Addr, s.cfg.ChainParams.DefaultPort)
365 err = s.cfg.ConnMgr.Connect(addr, true)
367 err = s.cfg.ConnMgr.RemoveByAddr(addr)
369 err = s.cfg.ConnMgr.Connect(addr, false)
371 return nil, &btcjson.RPCError{
372 Code: btcjson.ErrRPCInvalidParameter,
373 Message: "invalid subcommand for addnode",
378 return nil, &btcjson.RPCError{
379 Code: btcjson.ErrRPCInvalidParameter,
380 Message: err.Error(),
384 // no data returned unless an error.
388 // handleNode handles node commands.
389 func handleNode(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
390 c := cmd.(*btcjson.NodeCmd)
395 params := s.cfg.ChainParams
398 // If we have a valid uint disconnect by node id. Otherwise,
399 // attempt to disconnect by address, returning an error if a
400 // valid IP address is not supplied.
401 if nodeID, errN = strconv.ParseUint(c.Target, 10, 32); errN == nil {
402 err = s.cfg.ConnMgr.DisconnectByID(int32(nodeID))
404 if _, _, errP := net.SplitHostPort(c.Target); errP == nil || net.ParseIP(c.Target) != nil {
405 addr = normalizeAddress(c.Target, params.DefaultPort)
406 err = s.cfg.ConnMgr.DisconnectByAddr(addr)
408 return nil, &btcjson.RPCError{
409 Code: btcjson.ErrRPCInvalidParameter,
410 Message: "invalid address or node ID",
414 if err != nil && peerExists(s.cfg.ConnMgr, addr, int32(nodeID)) {
416 return nil, &btcjson.RPCError{
417 Code: btcjson.ErrRPCMisc,
418 Message: "can't disconnect a permanent peer, use remove",
423 // If we have a valid uint disconnect by node id. Otherwise,
424 // attempt to disconnect by address, returning an error if a
425 // valid IP address is not supplied.
426 if nodeID, errN = strconv.ParseUint(c.Target, 10, 32); errN == nil {
427 err = s.cfg.ConnMgr.RemoveByID(int32(nodeID))
429 if _, _, errP := net.SplitHostPort(c.Target); errP == nil || net.ParseIP(c.Target) != nil {
430 addr = normalizeAddress(c.Target, params.DefaultPort)
431 err = s.cfg.ConnMgr.RemoveByAddr(addr)
433 return nil, &btcjson.RPCError{
434 Code: btcjson.ErrRPCInvalidParameter,
435 Message: "invalid address or node ID",
439 if err != nil && peerExists(s.cfg.ConnMgr, addr, int32(nodeID)) {
440 return nil, &btcjson.RPCError{
441 Code: btcjson.ErrRPCMisc,
442 Message: "can't remove a temporary peer, use disconnect",
447 addr = normalizeAddress(c.Target, params.DefaultPort)
449 // Default to temporary connections.
451 if c.ConnectSubCmd != nil {
452 subCmd = *c.ConnectSubCmd
457 err = s.cfg.ConnMgr.Connect(addr, subCmd == "perm")
459 return nil, &btcjson.RPCError{
460 Code: btcjson.ErrRPCInvalidParameter,
461 Message: "invalid subcommand for node connect",
465 return nil, &btcjson.RPCError{
466 Code: btcjson.ErrRPCInvalidParameter,
467 Message: "invalid subcommand for node",
472 return nil, &btcjson.RPCError{
473 Code: btcjson.ErrRPCInvalidParameter,
474 Message: err.Error(),
478 // no data returned unless an error.
482 // peerExists determines if a certain peer is currently connected given
483 // information about all currently connected peers. Peer existence is
484 // determined using either a target address or node id.
485 func peerExists(connMgr rpcserverConnManager, addr string, nodeID int32) bool {
486 for _, p := range connMgr.ConnectedPeers() {
487 if p.ToPeer().ID() == nodeID || p.ToPeer().Addr() == addr {
494 // messageToHex serializes a message to the wire protocol encoding using the
495 // latest protocol version and returns a hex-encoded string of the result.
496 func messageToHex(msg wire.Message) (string, error) {
498 if err := msg.BtcEncode(&buf, maxProtocolVersion, wire.WitnessEncoding); err != nil {
499 context := fmt.Sprintf("Failed to encode msg of type %T", msg)
500 return "", internalRPCError(err.Error(), context)
503 return hex.EncodeToString(buf.Bytes()), nil
506 // handleCreateRawTransaction handles createrawtransaction commands.
507 func handleCreateRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
508 c := cmd.(*btcjson.CreateRawTransactionCmd)
510 // Validate the locktime, if given.
511 if c.LockTime != nil &&
512 (*c.LockTime < 0 || *c.LockTime > int64(wire.MaxTxInSequenceNum)) {
513 return nil, &btcjson.RPCError{
514 Code: btcjson.ErrRPCInvalidParameter,
515 Message: "Locktime out of range",
519 // Add all transaction inputs to a new transaction after performing
520 // some validity checks.
521 mtx := wire.NewMsgTx(wire.TxVersion)
522 for _, input := range c.Inputs {
523 txHash, err := chainhash.NewHashFromStr(input.Txid)
525 return nil, rpcDecodeHexError(input.Txid)
528 prevOut := wire.NewOutPoint(txHash, input.Vout)
529 txIn := wire.NewTxIn(prevOut, []byte{}, nil)
530 if c.LockTime != nil && *c.LockTime != 0 {
531 txIn.Sequence = wire.MaxTxInSequenceNum - 1
536 // Add all transaction outputs to the transaction after performing
537 // some validity checks.
538 params := s.cfg.ChainParams
539 for encodedAddr, amount := range c.Amounts {
540 // Ensure amount is in the valid range for monetary amounts.
541 if amount <= 0 || amount > btcutil.MaxSatoshi {
542 return nil, &btcjson.RPCError{
543 Code: btcjson.ErrRPCType,
544 Message: "Invalid amount",
548 // Decode the provided address.
549 addr, err := btcutil.DecodeAddress(encodedAddr, params)
551 return nil, &btcjson.RPCError{
552 Code: btcjson.ErrRPCInvalidAddressOrKey,
553 Message: "Invalid address or key: " + err.Error(),
557 // Ensure the address is one of the supported types and that
558 // the network encoded with the address matches the network the
559 // server is currently on.
561 case *btcutil.AddressPubKeyHash:
562 case *btcutil.AddressScriptHash:
564 return nil, &btcjson.RPCError{
565 Code: btcjson.ErrRPCInvalidAddressOrKey,
566 Message: "Invalid address or key",
569 if !addr.IsForNet(params) {
570 return nil, &btcjson.RPCError{
571 Code: btcjson.ErrRPCInvalidAddressOrKey,
572 Message: "Invalid address: " + encodedAddr +
573 " is for the wrong network",
577 // Create a new script which pays to the provided address.
578 pkScript, err := txscript.PayToAddrScript(addr)
580 context := "Failed to generate pay-to-address script"
581 return nil, internalRPCError(err.Error(), context)
584 // Convert the amount to satoshi.
585 satoshi, err := btcutil.NewAmount(amount)
587 context := "Failed to convert amount"
588 return nil, internalRPCError(err.Error(), context)
591 txOut := wire.NewTxOut(int64(satoshi), pkScript)
595 // Set the Locktime, if given.
596 if c.LockTime != nil {
597 mtx.LockTime = uint32(*c.LockTime)
600 // Return the serialized and hex-encoded transaction. Note that this
601 // is intentionally not directly returning because the first return
602 // value is a string and it would result in returning an empty string to
603 // the client instead of nothing (nil) in the case of an error.
604 mtxHex, err := messageToHex(mtx)
611 // handleDebugLevel handles debuglevel commands.
612 func handleDebugLevel(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
613 c := cmd.(*btcjson.DebugLevelCmd)
615 // Special show command to list supported subsystems.
616 if c.LevelSpec == "show" {
617 return fmt.Sprintf("Supported subsystems %v",
618 supportedSubsystems()), nil
621 err := parseAndSetDebugLevels(c.LevelSpec)
623 return nil, &btcjson.RPCError{
624 Code: btcjson.ErrRPCInvalidParams.Code,
625 Message: err.Error(),
632 // witnessToHex formats the passed witness stack as a slice of hex-encoded
633 // strings to be used in a JSON response.
634 func witnessToHex(witness wire.TxWitness) []string {
635 // Ensure nil is returned when there are no entries versus an empty
636 // slice so it can properly be omitted as necessary.
637 if len(witness) == 0 {
641 result := make([]string, 0, len(witness))
642 for _, wit := range witness {
643 result = append(result, hex.EncodeToString(wit))
649 // createVinList returns a slice of JSON objects for the inputs of the passed
651 func createVinList(mtx *wire.MsgTx) []btcjson.Vin {
652 // Coinbase transactions only have a single txin by definition.
653 vinList := make([]btcjson.Vin, len(mtx.TxIn))
654 if blockchain.IsCoinBaseTx(mtx) {
656 vinList[0].Coinbase = hex.EncodeToString(txIn.SignatureScript)
657 vinList[0].Sequence = txIn.Sequence
658 vinList[0].Witness = witnessToHex(txIn.Witness)
662 for i, txIn := range mtx.TxIn {
663 // The disassembled string will contain [error] inline
664 // if the script doesn't fully parse, so ignore the
666 disbuf, _ := txscript.DisasmString(txIn.SignatureScript)
668 vinEntry := &vinList[i]
669 vinEntry.Txid = txIn.PreviousOutPoint.Hash.String()
670 vinEntry.Vout = txIn.PreviousOutPoint.Index
671 vinEntry.Sequence = txIn.Sequence
672 vinEntry.ScriptSig = &btcjson.ScriptSig{
674 Hex: hex.EncodeToString(txIn.SignatureScript),
677 if mtx.HasWitness() {
678 vinEntry.Witness = witnessToHex(txIn.Witness)
685 // createVoutList returns a slice of JSON objects for the outputs of the passed
687 func createVoutList(mtx *wire.MsgTx, chainParams *chaincfg.Params, filterAddrMap map[string]struct{}) []btcjson.Vout {
688 voutList := make([]btcjson.Vout, 0, len(mtx.TxOut))
689 for i, v := range mtx.TxOut {
690 // The disassembled string will contain [error] inline if the
691 // script doesn't fully parse, so ignore the error here.
692 disbuf, _ := txscript.DisasmString(v.PkScript)
694 // Ignore the error here since an error means the script
695 // couldn't parse and there is no additional information about
697 scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(
698 v.PkScript, chainParams)
700 // Encode the addresses while checking if the address passes the
701 // filter when needed.
702 passesFilter := len(filterAddrMap) == 0
703 encodedAddrs := make([]string, len(addrs))
704 for j, addr := range addrs {
705 encodedAddr := addr.EncodeAddress()
706 encodedAddrs[j] = encodedAddr
708 // No need to check the map again if the filter already
713 if _, exists := filterAddrMap[encodedAddr]; exists {
722 var vout btcjson.Vout
724 vout.Value = btcutil.Amount(v.Value).ToBTC()
725 vout.ScriptPubKey.Addresses = encodedAddrs
726 vout.ScriptPubKey.Asm = disbuf
727 vout.ScriptPubKey.Hex = hex.EncodeToString(v.PkScript)
728 vout.ScriptPubKey.Type = scriptClass.String()
729 vout.ScriptPubKey.ReqSigs = int32(reqSigs)
731 voutList = append(voutList, vout)
737 // createTxRawResult converts the passed transaction and associated parameters
738 // to a raw transaction JSON object.
739 func createTxRawResult(chainParams *chaincfg.Params, mtx *wire.MsgTx,
740 txHash string, blkHeader *wire.BlockHeader, blkHash string,
741 blkHeight int32, chainHeight int32) (*btcjson.TxRawResult, error) {
743 mtxHex, err := messageToHex(mtx)
748 txReply := &btcjson.TxRawResult{
751 Hash: mtx.WitnessHash().String(),
752 Size: int32(mtx.SerializeSize()),
753 Vsize: int32(mempool.GetTxVirtualSize(btcutil.NewTx(mtx))),
754 Vin: createVinList(mtx),
755 Vout: createVoutList(mtx, chainParams, nil),
756 Version: mtx.Version,
757 LockTime: mtx.LockTime,
760 if blkHeader != nil {
761 // This is not a typo, they are identical in bitcoind as well.
762 txReply.Time = blkHeader.Timestamp.Unix()
763 txReply.Blocktime = blkHeader.Timestamp.Unix()
764 txReply.BlockHash = blkHash
765 txReply.Confirmations = uint64(1 + chainHeight - blkHeight)
771 // handleDecodeRawTransaction handles decoderawtransaction commands.
772 func handleDecodeRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
773 c := cmd.(*btcjson.DecodeRawTransactionCmd)
775 // Deserialize the transaction.
777 if len(hexStr)%2 != 0 {
778 hexStr = "0" + hexStr
780 serializedTx, err := hex.DecodeString(hexStr)
782 return nil, rpcDecodeHexError(hexStr)
785 err = mtx.Deserialize(bytes.NewReader(serializedTx))
787 return nil, &btcjson.RPCError{
788 Code: btcjson.ErrRPCDeserialization,
789 Message: "TX decode failed: " + err.Error(),
793 // Create and return the result.
794 txReply := btcjson.TxRawDecodeResult{
795 Txid: mtx.TxHash().String(),
796 Version: mtx.Version,
797 Locktime: mtx.LockTime,
798 Vin: createVinList(&mtx),
799 Vout: createVoutList(&mtx, s.cfg.ChainParams, nil),
804 // handleDecodeScript handles decodescript commands.
805 func handleDecodeScript(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
806 c := cmd.(*btcjson.DecodeScriptCmd)
808 // Convert the hex script to bytes.
809 hexStr := c.HexScript
810 if len(hexStr)%2 != 0 {
811 hexStr = "0" + hexStr
813 script, err := hex.DecodeString(hexStr)
815 return nil, rpcDecodeHexError(hexStr)
818 // The disassembled string will contain [error] inline if the script
819 // doesn't fully parse, so ignore the error here.
820 disbuf, _ := txscript.DisasmString(script)
822 // Get information about the script.
823 // Ignore the error here since an error means the script couldn't parse
824 // and there is no additinal information about it anyways.
825 scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(script,
827 addresses := make([]string, len(addrs))
828 for i, addr := range addrs {
829 addresses[i] = addr.EncodeAddress()
832 // Convert the script itself to a pay-to-script-hash address.
833 p2sh, err := btcutil.NewAddressScriptHash(script, s.cfg.ChainParams)
835 context := "Failed to convert script to pay-to-script-hash"
836 return nil, internalRPCError(err.Error(), context)
839 // Generate and return the reply.
840 reply := btcjson.DecodeScriptResult{
842 ReqSigs: int32(reqSigs),
843 Type: scriptClass.String(),
844 Addresses: addresses,
846 if scriptClass != txscript.ScriptHashTy {
847 reply.P2sh = p2sh.EncodeAddress()
852 // handleGenerate handles generate commands.
853 func handleGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
854 // Respond with an error if there are no addresses to pay the
855 // created blocks to.
856 if len(cfg.miningAddrs) == 0 {
857 return nil, &btcjson.RPCError{
858 Code: btcjson.ErrRPCInternal.Code,
859 Message: "No payment addresses specified " +
864 // Respond with an error if there's virtually 0 chance of mining a block
866 if !s.cfg.ChainParams.GenerateSupported {
867 return nil, &btcjson.RPCError{
868 Code: btcjson.ErrRPCDifficulty,
869 Message: fmt.Sprintf("No support for `generate` on "+
870 "the current network, %s, as it's unlikely to "+
871 "be possible to main a block with the CPU.",
872 s.cfg.ChainParams.Net),
876 c := cmd.(*btcjson.GenerateCmd)
878 // Respond with an error if the client is requesting 0 blocks to be generated.
879 if c.NumBlocks == 0 {
880 return nil, &btcjson.RPCError{
881 Code: btcjson.ErrRPCInternal.Code,
882 Message: "Please request a nonzero number of blocks to generate.",
887 reply := make([]string, c.NumBlocks)
889 blockHashes, err := s.cfg.CPUMiner.GenerateNBlocks(c.NumBlocks)
891 return nil, &btcjson.RPCError{
892 Code: btcjson.ErrRPCInternal.Code,
893 Message: err.Error(),
897 // Mine the correct number of blocks, assigning the hex representation of the
898 // hash of each one to its place in the reply.
899 for i, hash := range blockHashes {
900 reply[i] = hash.String()
906 // handleGetAddedNodeInfo handles getaddednodeinfo commands.
907 func handleGetAddedNodeInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
908 c := cmd.(*btcjson.GetAddedNodeInfoCmd)
910 // Retrieve a list of persistent (added) peers from the server and
911 // filter the list of peers per the specified address (if any).
912 peers := s.cfg.ConnMgr.PersistentPeers()
916 for i, peer := range peers {
917 if peer.ToPeer().Addr() == node {
918 peers = peers[i : i+1]
923 return nil, &btcjson.RPCError{
924 Code: btcjson.ErrRPCClientNodeNotAdded,
925 Message: "Node has not been added",
930 // Without the dns flag, the result is just a slice of the addresses as
933 results := make([]string, 0, len(peers))
934 for _, peer := range peers {
935 results = append(results, peer.ToPeer().Addr())
940 // With the dns flag, the result is an array of JSON objects which
941 // include the result of DNS lookups for each peer.
942 results := make([]*btcjson.GetAddedNodeInfoResult, 0, len(peers))
943 for _, rpcPeer := range peers {
944 // Set the "address" of the peer which could be an ip address
946 peer := rpcPeer.ToPeer()
947 var result btcjson.GetAddedNodeInfoResult
948 result.AddedNode = peer.Addr()
949 result.Connected = btcjson.Bool(peer.Connected())
951 // Split the address into host and port portions so we can do
952 // a DNS lookup against the host. When no port is specified in
953 // the address, just use the address as the host.
954 host, _, err := net.SplitHostPort(peer.Addr())
961 case net.ParseIP(host) != nil, strings.HasSuffix(host, ".onion"):
962 ipList = make([]string, 1)
965 // Do a DNS lookup for the address. If the lookup fails, just
967 ips, err := btcdLookup(host)
969 ipList = make([]string, 1)
973 ipList = make([]string, 0, len(ips))
974 for _, ip := range ips {
975 ipList = append(ipList, ip.String())
979 // Add the addresses and connection info to the result.
980 addrs := make([]btcjson.GetAddedNodeInfoResultAddr, 0, len(ipList))
981 for _, ip := range ipList {
982 var addr btcjson.GetAddedNodeInfoResultAddr
984 addr.Connected = "false"
985 if ip == host && peer.Connected() {
986 addr.Connected = directionString(peer.Inbound())
988 addrs = append(addrs, addr)
990 result.Addresses = &addrs
991 results = append(results, &result)
996 // handleGetBestBlock implements the getbestblock command.
997 func handleGetBestBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
998 // All other "get block" commands give either the height, the
999 // hash, or both but require the block SHA. This gets both for
1001 best := s.cfg.Chain.BestSnapshot()
1002 result := &btcjson.GetBestBlockResult{
1003 Hash: best.Hash.String(),
1004 Height: best.Height,
1009 // handleGetBestBlockHash implements the getbestblockhash command.
1010 func handleGetBestBlockHash(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
1011 best := s.cfg.Chain.BestSnapshot()
1012 return best.Hash.String(), nil
1015 // getDifficultyRatio returns the proof-of-work difficulty as a multiple of the
1016 // minimum difficulty using the passed bits field from the header of a block.
1017 func getDifficultyRatio(bits uint32, params *chaincfg.Params) float64 {
1018 // The minimum difficulty is the max possible proof-of-work limit bits
1019 // converted back to a number. Note this is not the same as the proof of
1020 // work limit directly because the block difficulty is encoded in a block
1021 // with the compact form which loses precision.
1022 max := blockchain.CompactToBig(params.PowLimitBits)
1023 target := blockchain.CompactToBig(bits)
1025 difficulty := new(big.Rat).SetFrac(max, target)
1026 outString := difficulty.FloatString(8)
1027 diff, err := strconv.ParseFloat(outString, 64)
1029 rpcsLog.Errorf("Cannot get difficulty: %v", err)
1035 // handleGetBlock implements the getblock command.
1036 func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
1037 c := cmd.(*btcjson.GetBlockCmd)
1039 // Load the raw block bytes from the database.
1040 hash, err := chainhash.NewHashFromStr(c.Hash)
1042 return nil, rpcDecodeHexError(c.Hash)
1045 err = s.cfg.DB.View(func(dbTx database.Tx) error {
1047 blkBytes, err = dbTx.FetchBlock(hash)
1051 return nil, &btcjson.RPCError{
1052 Code: btcjson.ErrRPCBlockNotFound,
1053 Message: "Block not found",
1057 // When the verbose flag isn't set, simply return the serialized block
1058 // as a hex-encoded string.
1059 if c.Verbose != nil && !*c.Verbose {
1060 return hex.EncodeToString(blkBytes), nil
1063 // The verbose flag is set, so generate the JSON object and return it.
1065 // Deserialize the block.
1066 blk, err := btcutil.NewBlockFromBytes(blkBytes)
1068 context := "Failed to deserialize block"
1069 return nil, internalRPCError(err.Error(), context)
1072 // Get the block height from chain.
1073 blockHeight, err := s.cfg.Chain.BlockHeightByHash(hash)
1075 context := "Failed to obtain block height"
1076 return nil, internalRPCError(err.Error(), context)
1078 blk.SetHeight(blockHeight)
1079 best := s.cfg.Chain.BestSnapshot()
1081 // Get next block hash unless there are none.
1082 var nextHashString string
1083 if blockHeight < best.Height {
1084 nextHash, err := s.cfg.Chain.BlockHashByHeight(blockHeight + 1)
1086 context := "No next block"
1087 return nil, internalRPCError(err.Error(), context)
1089 nextHashString = nextHash.String()
1092 params := s.cfg.ChainParams
1093 blockHeader := &blk.MsgBlock().Header
1094 blockReply := btcjson.GetBlockVerboseResult{
1096 Version: blockHeader.Version,
1097 VersionHex: fmt.Sprintf("%08x", blockHeader.Version),
1098 MerkleRoot: blockHeader.MerkleRoot.String(),
1099 PreviousHash: blockHeader.PrevBlock.String(),
1100 Nonce: blockHeader.Nonce,
1101 Time: blockHeader.Timestamp.Unix(),
1102 Confirmations: uint64(1 + best.Height - blockHeight),
1103 Height: int64(blockHeight),
1104 Size: int32(len(blkBytes)),
1105 StrippedSize: int32(blk.MsgBlock().SerializeSizeStripped()),
1106 Weight: int32(blockchain.GetBlockWeight(blk)),
1107 Bits: strconv.FormatInt(int64(blockHeader.Bits), 16),
1108 Difficulty: getDifficultyRatio(blockHeader.Bits, params),
1109 NextHash: nextHashString,
1112 if c.VerboseTx == nil || !*c.VerboseTx {
1113 transactions := blk.Transactions()
1114 txNames := make([]string, len(transactions))
1115 for i, tx := range transactions {
1116 txNames[i] = tx.Hash().String()
1119 blockReply.Tx = txNames
1121 txns := blk.Transactions()
1122 rawTxns := make([]btcjson.TxRawResult, len(txns))
1123 for i, tx := range txns {
1124 rawTxn, err := createTxRawResult(params, tx.MsgTx(),
1125 tx.Hash().String(), blockHeader, hash.String(),
1126 blockHeight, best.Height)
1130 rawTxns[i] = *rawTxn
1132 blockReply.RawTx = rawTxns
1135 return blockReply, nil
1138 // softForkStatus converts a ThresholdState state into a human readable string
1139 // corresponding to the particular state.
1140 func softForkStatus(state blockchain.ThresholdState) (string, error) {
1142 case blockchain.ThresholdDefined:
1143 return "defined", nil
1144 case blockchain.ThresholdStarted:
1145 return "started", nil
1146 case blockchain.ThresholdLockedIn:
1147 return "lockedin", nil
1148 case blockchain.ThresholdActive:
1149 return "active", nil
1150 case blockchain.ThresholdFailed:
1151 return "failed", nil
1153 return "", fmt.Errorf("unknown deployment state: %v", state)
1157 // handleGetBlockChainInfo implements the getblockchaininfo command.
1158 func handleGetBlockChainInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
1159 // Obtain a snapshot of the current best known blockchain state. We'll
1160 // populate the response to this call primarily from this snapshot.
1161 params := s.cfg.ChainParams
1162 chain := s.cfg.Chain
1163 chainSnapshot := chain.BestSnapshot()
1165 chainInfo := &btcjson.GetBlockChainInfoResult{
1167 Blocks: chainSnapshot.Height,
1168 Headers: chainSnapshot.Height,
1169 BestBlockHash: chainSnapshot.Hash.String(),
1170 Difficulty: getDifficultyRatio(chainSnapshot.Bits, params),
1171 MedianTime: chainSnapshot.MedianTime.Unix(),
1173 Bip9SoftForks: make(map[string]*btcjson.Bip9SoftForkDescription),
1176 // Next, populate the response with information describing the current
1177 // status of soft-forks deployed via the super-majority block
1178 // signalling mechanism.
1179 height := chainSnapshot.Height
1180 chainInfo.SoftForks = []*btcjson.SoftForkDescription{
1185 Status bool `json:"status"`
1187 Status: height >= params.BIP0034Height,
1194 Status bool `json:"status"`
1196 Status: height >= params.BIP0066Height,
1203 Status bool `json:"status"`
1205 Status: height >= params.BIP0065Height,
1210 // Finally, query the BIP0009 version bits state for all currently
1211 // defined BIP0009 soft-fork deployments.
1212 for deployment, deploymentDetails := range params.Deployments {
1213 // Map the integer deployment ID into a human readable
1217 case chaincfg.DeploymentTestDummy:
1220 case chaincfg.DeploymentCSV:
1223 case chaincfg.DeploymentSegwit:
1227 return nil, &btcjson.RPCError{
1228 Code: btcjson.ErrRPCInternal.Code,
1229 Message: fmt.Sprintf("Unknown deployment %v "+
1230 "detected", deployment),
1234 // Query the chain for the current status of the deployment as
1235 // identified by its deployment ID.
1236 deploymentStatus, err := chain.ThresholdState(uint32(deployment))
1238 context := "Failed to obtain deployment status"
1239 return nil, internalRPCError(err.Error(), context)
1242 // Attempt to convert the current deployment status into a
1243 // human readable string. If the status is unrecognized, then a
1244 // non-nil error is returned.
1245 statusString, err := softForkStatus(deploymentStatus)
1247 return nil, &btcjson.RPCError{
1248 Code: btcjson.ErrRPCInternal.Code,
1249 Message: fmt.Sprintf("unknown deployment status: %v",
1254 // Finally, populate the soft-fork description with all the
1255 // information gathered above.
1256 chainInfo.Bip9SoftForks[forkName] = &btcjson.Bip9SoftForkDescription{
1257 Status: strings.ToLower(statusString),
1258 Bit: deploymentDetails.BitNumber,
1259 StartTime: int64(deploymentDetails.StartTime),
1260 Timeout: int64(deploymentDetails.ExpireTime),
1264 return chainInfo, nil
1267 // handleGetBlockCount implements the getblockcount command.
1268 func handleGetBlockCount(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
1269 best := s.cfg.Chain.BestSnapshot()
1270 return int64(best.Height), nil
1273 // handleGetBlockHash implements the getblockhash command.
1274 func handleGetBlockHash(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
1275 c := cmd.(*btcjson.GetBlockHashCmd)
1276 hash, err := s.cfg.Chain.BlockHashByHeight(int32(c.Index))
1278 return nil, &btcjson.RPCError{
1279 Code: btcjson.ErrRPCOutOfRange,
1280 Message: "Block number out of range",
1284 return hash.String(), nil
1287 // handleGetBlockHeader implements the getblockheader command.
1288 func handleGetBlockHeader(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
1289 c := cmd.(*btcjson.GetBlockHeaderCmd)
1291 // Fetch the header from chain.
1292 hash, err := chainhash.NewHashFromStr(c.Hash)
1294 return nil, rpcDecodeHexError(c.Hash)
1296 blockHeader, err := s.cfg.Chain.FetchHeader(hash)
1298 return nil, &btcjson.RPCError{
1299 Code: btcjson.ErrRPCBlockNotFound,
1300 Message: "Block not found",
1304 // When the verbose flag isn't set, simply return the serialized block
1305 // header as a hex-encoded string.
1306 if c.Verbose != nil && !*c.Verbose {
1307 var headerBuf bytes.Buffer
1308 err := blockHeader.Serialize(&headerBuf)
1310 context := "Failed to serialize block header"
1311 return nil, internalRPCError(err.Error(), context)
1313 return hex.EncodeToString(headerBuf.Bytes()), nil
1316 // The verbose flag is set, so generate the JSON object and return it.
1318 // Get the block height from chain.
1319 blockHeight, err := s.cfg.Chain.BlockHeightByHash(hash)
1321 context := "Failed to obtain block height"
1322 return nil, internalRPCError(err.Error(), context)
1324 best := s.cfg.Chain.BestSnapshot()
1326 // Get next block hash unless there are none.
1327 var nextHashString string
1328 if blockHeight < best.Height {
1329 nextHash, err := s.cfg.Chain.BlockHashByHeight(blockHeight + 1)
1331 context := "No next block"
1332 return nil, internalRPCError(err.Error(), context)
1334 nextHashString = nextHash.String()
1337 params := s.cfg.ChainParams
1338 blockHeaderReply := btcjson.GetBlockHeaderVerboseResult{
1340 Confirmations: uint64(1 + best.Height - blockHeight),
1341 Height: blockHeight,
1342 Version: blockHeader.Version,
1343 VersionHex: fmt.Sprintf("%08x", blockHeader.Version),
1344 MerkleRoot: blockHeader.MerkleRoot.String(),
1345 NextHash: nextHashString,
1346 PreviousHash: blockHeader.PrevBlock.String(),
1347 Nonce: uint64(blockHeader.Nonce),
1348 Time: blockHeader.Timestamp.Unix(),
1349 Bits: strconv.FormatInt(int64(blockHeader.Bits), 16),
1350 Difficulty: getDifficultyRatio(blockHeader.Bits, params),
1352 return blockHeaderReply, nil
1355 // encodeTemplateID encodes the passed details into an ID that can be used to
1356 // uniquely identify a block template.
1357 func encodeTemplateID(prevHash *chainhash.Hash, lastGenerated time.Time) string {
1358 return fmt.Sprintf("%s-%d", prevHash.String(), lastGenerated.Unix())
1361 // decodeTemplateID decodes an ID that is used to uniquely identify a block
1362 // template. This is mainly used as a mechanism to track when to update clients
1363 // that are using long polling for block templates. The ID consists of the
1364 // previous block hash for the associated template and the time the associated
1365 // template was generated.
1366 func decodeTemplateID(templateID string) (*chainhash.Hash, int64, error) {
1367 fields := strings.Split(templateID, "-")
1368 if len(fields) != 2 {
1369 return nil, 0, errors.New("invalid longpollid format")
1372 prevHash, err := chainhash.NewHashFromStr(fields[0])
1374 return nil, 0, errors.New("invalid longpollid format")
1376 lastGenerated, err := strconv.ParseInt(fields[1], 10, 64)
1378 return nil, 0, errors.New("invalid longpollid format")
1381 return prevHash, lastGenerated, nil
1384 // notifyLongPollers notifies any channels that have been registered to be
1385 // notified when block templates are stale.
1387 // This function MUST be called with the state locked.
1388 func (state *gbtWorkState) notifyLongPollers(latestHash *chainhash.Hash, lastGenerated time.Time) {
1389 // Notify anything that is waiting for a block template update from a
1390 // hash which is not the hash of the tip of the best chain since their
1391 // work is now invalid.
1392 for hash, channels := range state.notifyMap {
1393 if !hash.IsEqual(latestHash) {
1394 for _, c := range channels {
1397 delete(state.notifyMap, hash)
1401 // Return now if the provided last generated timestamp has not been
1403 if lastGenerated.IsZero() {
1407 // Return now if there is nothing registered for updates to the current
1409 channels, ok := state.notifyMap[*latestHash]
1414 // Notify anything that is waiting for a block template update from a
1415 // block template generated before the most recently generated block
1417 lastGeneratedUnix := lastGenerated.Unix()
1418 for lastGen, c := range channels {
1419 if lastGen < lastGeneratedUnix {
1421 delete(channels, lastGen)
1425 // Remove the entry altogether if there are no more registered
1427 if len(channels) == 0 {
1428 delete(state.notifyMap, *latestHash)
1432 // NotifyBlockConnected uses the newly-connected block to notify any long poll
1433 // clients with a new block template when their existing block template is
1434 // stale due to the newly connected block.
1435 func (state *gbtWorkState) NotifyBlockConnected(blockHash *chainhash.Hash) {
1438 defer state.Unlock()
1440 state.notifyLongPollers(blockHash, state.lastTxUpdate)
1444 // NotifyMempoolTx uses the new last updated time for the transaction memory
1445 // pool to notify any long poll clients with a new block template when their
1446 // existing block template is stale due to enough time passing and the contents
1447 // of the memory pool changing.
1448 func (state *gbtWorkState) NotifyMempoolTx(lastUpdated time.Time) {
1451 defer state.Unlock()
1453 // No need to notify anything if no block templates have been generated
1455 if state.prevHash == nil || state.lastGenerated.IsZero() {
1459 if time.Now().After(state.lastGenerated.Add(time.Second *
1460 gbtRegenerateSeconds)) {
1462 state.notifyLongPollers(state.prevHash, lastUpdated)
1467 // templateUpdateChan returns a channel that will be closed once the block
1468 // template associated with the passed previous hash and last generated time
1469 // is stale. The function will return existing channels for duplicate
1470 // parameters which allows multiple clients to wait for the same block template
1471 // without requiring a different channel for each client.
1473 // This function MUST be called with the state locked.
1474 func (state *gbtWorkState) templateUpdateChan(prevHash *chainhash.Hash, lastGenerated int64) chan struct{} {
1475 // Either get the current list of channels waiting for updates about
1476 // changes to block template for the previous hash or create a new one.
1477 channels, ok := state.notifyMap[*prevHash]
1479 m := make(map[int64]chan struct{})
1480 state.notifyMap[*prevHash] = m
1484 // Get the current channel associated with the time the block template
1485 // was last generated or create a new one.
1486 c, ok := channels[lastGenerated]
1488 c = make(chan struct{})
1489 channels[lastGenerated] = c
1495 // updateBlockTemplate creates or updates a block template for the work state.
1496 // A new block template will be generated when the current best block has
1497 // changed or the transactions in the memory pool have been updated and it has
1498 // been long enough since the last template was generated. Otherwise, the
1499 // timestamp for the existing block template is updated (and possibly the
1500 // difficulty on testnet per the consesus rules). Finally, if the
1501 // useCoinbaseValue flag is false and the existing block template does not
1502 // already contain a valid payment address, the block template will be updated
1503 // with a randomly selected payment address from the list of configured
1506 // This function MUST be called with the state locked.
1507 func (state *gbtWorkState) updateBlockTemplate(s *rpcServer, useCoinbaseValue bool) error {
1508 generator := s.cfg.Generator
1509 lastTxUpdate := generator.TxSource().LastUpdated()
1510 if lastTxUpdate.IsZero() {
1511 lastTxUpdate = time.Now()
1514 // Generate a new block template when the current best block has
1515 // changed or the transactions in the memory pool have been updated and
1516 // it has been at least gbtRegenerateSecond since the last template was
1518 var msgBlock *wire.MsgBlock
1519 var targetDifficulty string
1520 latestHash := &s.cfg.Chain.BestSnapshot().Hash
1521 template := state.template
1522 if template == nil || state.prevHash == nil ||
1523 !state.prevHash.IsEqual(latestHash) ||
1524 (state.lastTxUpdate != lastTxUpdate &&
1525 time.Now().After(state.lastGenerated.Add(time.Second*
1526 gbtRegenerateSeconds))) {
1528 // Reset the previous best hash the block template was generated
1529 // against so any errors below cause the next invocation to try
1531 state.prevHash = nil
1533 // Choose a payment address at random if the caller requests a
1534 // full coinbase as opposed to only the pertinent details needed
1535 // to create their own coinbase.
1536 var payAddr btcutil.Address
1537 if !useCoinbaseValue {
1538 payAddr = cfg.miningAddrs[rand.Intn(len(cfg.miningAddrs))]
1541 // Create a new block template that has a coinbase which anyone
1542 // can redeem. This is only acceptable because the returned
1543 // block template doesn't include the coinbase, so the caller
1544 // will ultimately create their own coinbase which pays to the
1545 // appropriate address(es).
1546 blkTemplate, err := generator.NewBlockTemplate(payAddr)
1548 return internalRPCError("Failed to create new block "+
1549 "template: "+err.Error(), "")
1551 template = blkTemplate
1552 msgBlock = template.Block
1553 targetDifficulty = fmt.Sprintf("%064x",
1554 blockchain.CompactToBig(msgBlock.Header.Bits))
1556 // Get the minimum allowed timestamp for the block based on the
1557 // median timestamp of the last several blocks per the chain
1559 best := s.cfg.Chain.BestSnapshot()
1560 minTimestamp := mining.MinimumMedianTime(best)
1562 // Update work state to ensure another block template isn't
1563 // generated until needed.
1564 state.template = template
1565 state.lastGenerated = time.Now()
1566 state.lastTxUpdate = lastTxUpdate
1567 state.prevHash = latestHash
1568 state.minTimestamp = minTimestamp
1570 rpcsLog.Debugf("Generated block template (timestamp %v, "+
1571 "target %s, merkle root %s)",
1572 msgBlock.Header.Timestamp, targetDifficulty,
1573 msgBlock.Header.MerkleRoot)
1575 // Notify any clients that are long polling about the new
1577 state.notifyLongPollers(latestHash, lastTxUpdate)
1579 // At this point, there is a saved block template and another
1580 // request for a template was made, but either the available
1581 // transactions haven't change or it hasn't been long enough to
1582 // trigger a new block template to be generated. So, update the
1583 // existing block template.
1585 // When the caller requires a full coinbase as opposed to only
1586 // the pertinent details needed to create their own coinbase,
1587 // add a payment address to the output of the coinbase of the
1588 // template if it doesn't already have one. Since this requires
1589 // mining addresses to be specified via the config, an error is
1590 // returned if none have been specified.
1591 if !useCoinbaseValue && !template.ValidPayAddress {
1592 // Choose a payment address at random.
1593 payToAddr := cfg.miningAddrs[rand.Intn(len(cfg.miningAddrs))]
1595 // Update the block coinbase output of the template to
1596 // pay to the randomly selected payment address.
1597 pkScript, err := txscript.PayToAddrScript(payToAddr)
1599 context := "Failed to create pay-to-addr script"
1600 return internalRPCError(err.Error(), context)
1602 template.Block.Transactions[0].TxOut[0].PkScript = pkScript
1603 template.ValidPayAddress = true
1605 // Update the merkle root.
1606 block := btcutil.NewBlock(template.Block)
1607 merkles := blockchain.BuildMerkleTreeStore(block.Transactions(), false)
1608 template.Block.Header.MerkleRoot = *merkles[len(merkles)-1]
1611 // Set locals for convenience.
1612 msgBlock = template.Block
1613 targetDifficulty = fmt.Sprintf("%064x",
1614 blockchain.CompactToBig(msgBlock.Header.Bits))
1616 // Update the time of the block template to the current time
1617 // while accounting for the median time of the past several
1618 // blocks per the chain consensus rules.
1619 generator.UpdateBlockTime(msgBlock)
1620 msgBlock.Header.Nonce = 0
1622 rpcsLog.Debugf("Updated block template (timestamp %v, "+
1623 "target %s)", msgBlock.Header.Timestamp,
1630 // blockTemplateResult returns the current block template associated with the
1631 // state as a btcjson.GetBlockTemplateResult that is ready to be encoded to JSON
1632 // and returned to the caller.
1634 // This function MUST be called with the state locked.
1635 func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld *bool) (*btcjson.GetBlockTemplateResult, error) {
1636 // Ensure the timestamps are still in valid range for the template.
1637 // This should really only ever happen if the local clock is changed
1638 // after the template is generated, but it's important to avoid serving
1639 // invalid block templates.
1640 template := state.template
1641 msgBlock := template.Block
1642 header := &msgBlock.Header
1643 adjustedTime := state.timeSource.AdjustedTime()
1644 maxTime := adjustedTime.Add(time.Second * blockchain.MaxTimeOffsetSeconds)
1645 if header.Timestamp.After(maxTime) {
1646 return nil, &btcjson.RPCError{
1647 Code: btcjson.ErrRPCOutOfRange,
1648 Message: fmt.Sprintf("The template time is after the "+
1649 "maximum allowed time for a block - template "+
1650 "time %v, maximum time %v", adjustedTime,
1655 // Convert each transaction in the block template to a template result
1656 // transaction. The result does not include the coinbase, so notice
1657 // the adjustments to the various lengths and indices.
1658 numTx := len(msgBlock.Transactions)
1659 transactions := make([]btcjson.GetBlockTemplateResultTx, 0, numTx-1)
1660 txIndex := make(map[chainhash.Hash]int64, numTx)
1661 for i, tx := range msgBlock.Transactions {
1662 txHash := tx.TxHash()
1663 txIndex[txHash] = int64(i)
1665 // Skip the coinbase transaction.
1670 // Create an array of 1-based indices to transactions that come
1671 // before this one in the transactions list which this one
1672 // depends on. This is necessary since the created block must
1673 // ensure proper ordering of the dependencies. A map is used
1674 // before creating the final array to prevent duplicate entries
1675 // when multiple inputs reference the same transaction.
1676 dependsMap := make(map[int64]struct{})
1677 for _, txIn := range tx.TxIn {
1678 if idx, ok := txIndex[txIn.PreviousOutPoint.Hash]; ok {
1679 dependsMap[idx] = struct{}{}
1682 depends := make([]int64, 0, len(dependsMap))
1683 for idx := range dependsMap {
1684 depends = append(depends, idx)
1687 // Serialize the transaction for later conversion to hex.
1688 txBuf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
1689 if err := tx.Serialize(txBuf); err != nil {
1690 context := "Failed to serialize transaction"
1691 return nil, internalRPCError(err.Error(), context)
1694 bTx := btcutil.NewTx(tx)
1695 resultTx := btcjson.GetBlockTemplateResultTx{
1696 Data: hex.EncodeToString(txBuf.Bytes()),
1697 Hash: txHash.String(),
1699 Fee: template.Fees[i],
1700 SigOps: template.SigOpCosts[i],
1701 Weight: blockchain.GetTransactionWeight(bTx),
1703 transactions = append(transactions, resultTx)
1706 // Generate the block template reply. Note that following mutations are
1707 // implied by the included or omission of fields:
1708 // Including MinTime -> time/decrement
1709 // Omitting CoinbaseTxn -> coinbase, generation
1710 targetDifficulty := fmt.Sprintf("%064x", blockchain.CompactToBig(header.Bits))
1711 templateID := encodeTemplateID(state.prevHash, state.lastGenerated)
1712 reply := btcjson.GetBlockTemplateResult{
1713 Bits: strconv.FormatInt(int64(header.Bits), 16),
1714 CurTime: header.Timestamp.Unix(),
1715 Height: int64(template.Height),
1716 PreviousHash: header.PrevBlock.String(),
1717 WeightLimit: blockchain.MaxBlockWeight,
1718 SigOpLimit: blockchain.MaxBlockSigOpsCost,
1719 SizeLimit: wire.MaxBlockPayload,
1720 Transactions: transactions,
1721 Version: header.Version,
1722 LongPollID: templateID,
1723 SubmitOld: submitOld,
1724 Target: targetDifficulty,
1725 MinTime: state.minTimestamp.Unix(),
1726 MaxTime: maxTime.Unix(),
1727 Mutable: gbtMutableFields,
1728 NonceRange: gbtNonceRange,
1729 Capabilities: gbtCapabilities,
1731 // If the generated block template includes transactions with witness
1732 // data, then include the witness commitment in the GBT result.
1733 if template.WitnessCommitment != nil {
1734 reply.DefaultWitnessCommitment = hex.EncodeToString(template.WitnessCommitment)
1737 if useCoinbaseValue {
1738 reply.CoinbaseAux = gbtCoinbaseAux
1739 reply.CoinbaseValue = &msgBlock.Transactions[0].TxOut[0].Value
1741 // Ensure the template has a valid payment address associated
1742 // with it when a full coinbase is requested.
1743 if !template.ValidPayAddress {
1744 return nil, &btcjson.RPCError{
1745 Code: btcjson.ErrRPCInternal.Code,
1746 Message: "A coinbase transaction has been " +
1747 "requested, but the server has not " +
1748 "been configured with any payment " +
1749 "addresses via --miningaddr",
1753 // Serialize the transaction for conversion to hex.
1754 tx := msgBlock.Transactions[0]
1755 txBuf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
1756 if err := tx.Serialize(txBuf); err != nil {
1757 context := "Failed to serialize transaction"
1758 return nil, internalRPCError(err.Error(), context)
1761 resultTx := btcjson.GetBlockTemplateResultTx{
1762 Data: hex.EncodeToString(txBuf.Bytes()),
1763 Hash: tx.TxHash().String(),
1765 Fee: template.Fees[0],
1766 SigOps: template.SigOpCosts[0],
1769 reply.CoinbaseTxn = &resultTx
1775 // handleGetBlockTemplateLongPoll is a helper for handleGetBlockTemplateRequest
1776 // which deals with handling long polling for block templates. When a caller
1777 // sends a request with a long poll ID that was previously returned, a response
1778 // is not sent until the caller should stop working on the previous block
1779 // template in favor of the new one. In particular, this is the case when the
1780 // old block template is no longer valid due to a solution already being found
1781 // and added to the block chain, or new transactions have shown up and some time
1782 // has passed without finding a solution.
1784 // See https://en.bitcoin.it/wiki/BIP_0022 for more details.
1785 func handleGetBlockTemplateLongPoll(s *rpcServer, longPollID string, useCoinbaseValue bool, closeChan <-chan struct{}) (interface{}, error) {
1786 state := s.gbtWorkState
1788 // The state unlock is intentionally not deferred here since it needs to
1789 // be manually unlocked before waiting for a notification about block
1790 // template changes.
1792 if err := state.updateBlockTemplate(s, useCoinbaseValue); err != nil {
1797 // Just return the current block template if the long poll ID provided by
1798 // the caller is invalid.
1799 prevHash, lastGenerated, err := decodeTemplateID(longPollID)
1801 result, err := state.blockTemplateResult(useCoinbaseValue, nil)
1811 // Return the block template now if the specific block template
1812 // identified by the long poll ID no longer matches the current block
1813 // template as this means the provided template is stale.
1814 prevTemplateHash := &state.template.Block.Header.PrevBlock
1815 if !prevHash.IsEqual(prevTemplateHash) ||
1816 lastGenerated != state.lastGenerated.Unix() {
1818 // Include whether or not it is valid to submit work against the
1819 // old block template depending on whether or not a solution has
1820 // already been found and added to the block chain.
1821 submitOld := prevHash.IsEqual(prevTemplateHash)
1822 result, err := state.blockTemplateResult(useCoinbaseValue,
1833 // Register the previous hash and last generated time for notifications
1834 // Get a channel that will be notified when the template associated with
1835 // the provided ID is stale and a new block template should be returned to
1837 longPollChan := state.templateUpdateChan(prevHash, lastGenerated)
1841 // When the client closes before it's time to send a reply, just return
1842 // now so the goroutine doesn't hang around.
1844 return nil, ErrClientQuit
1846 // Wait until signal received to send the reply.
1847 case <-longPollChan:
1851 // Get the lastest block template
1853 defer state.Unlock()
1855 if err := state.updateBlockTemplate(s, useCoinbaseValue); err != nil {
1859 // Include whether or not it is valid to submit work against the old
1860 // block template depending on whether or not a solution has already
1861 // been found and added to the block chain.
1862 submitOld := prevHash.IsEqual(&state.template.Block.Header.PrevBlock)
1863 result, err := state.blockTemplateResult(useCoinbaseValue, &submitOld)
1871 // handleGetBlockTemplateRequest is a helper for handleGetBlockTemplate which
1872 // deals with generating and returning block templates to the caller. It
1873 // handles both long poll requests as specified by BIP 0022 as well as regular
1874 // requests. In addition, it detects the capabilities reported by the caller
1875 // in regards to whether or not it supports creating its own coinbase (the
1876 // coinbasetxn and coinbasevalue capabilities) and modifies the returned block
1877 // template accordingly.
1878 func handleGetBlockTemplateRequest(s *rpcServer, request *btcjson.TemplateRequest, closeChan <-chan struct{}) (interface{}, error) {
1879 // Extract the relevant passed capabilities and restrict the result to
1880 // either a coinbase value or a coinbase transaction object depending on
1881 // the request. Default to only providing a coinbase value.
1882 useCoinbaseValue := true
1884 var hasCoinbaseValue, hasCoinbaseTxn bool
1885 for _, capability := range request.Capabilities {
1888 hasCoinbaseTxn = true
1889 case "coinbasevalue":
1890 hasCoinbaseValue = true
1894 if hasCoinbaseTxn && !hasCoinbaseValue {
1895 useCoinbaseValue = false
1899 // When a coinbase transaction has been requested, respond with an error
1900 // if there are no addresses to pay the created block template to.
1901 if !useCoinbaseValue && len(cfg.miningAddrs) == 0 {
1902 return nil, &btcjson.RPCError{
1903 Code: btcjson.ErrRPCInternal.Code,
1904 Message: "A coinbase transaction has been requested, " +
1905 "but the server has not been configured with " +
1906 "any payment addresses via --miningaddr",
1910 // Return an error if there are no peers connected since there is no
1911 // way to relay a found block or receive transactions to work on.
1912 // However, allow this state when running in the regression test or
1913 // simulation test mode.
1914 if !(cfg.RegressionTest || cfg.SimNet) &&
1915 s.cfg.ConnMgr.ConnectedCount() == 0 {
1917 return nil, &btcjson.RPCError{
1918 Code: btcjson.ErrRPCClientNotConnected,
1919 Message: "Bitcoin is not connected",
1923 // No point in generating or accepting work before the chain is synced.
1924 currentHeight := s.cfg.Chain.BestSnapshot().Height
1925 if currentHeight != 0 && !s.cfg.SyncMgr.IsCurrent() {
1926 return nil, &btcjson.RPCError{
1927 Code: btcjson.ErrRPCClientInInitialDownload,
1928 Message: "Bitcoin is downloading blocks...",
1932 // When a long poll ID was provided, this is a long poll request by the
1933 // client to be notified when block template referenced by the ID should
1934 // be replaced with a new one.
1935 if request != nil && request.LongPollID != "" {
1936 return handleGetBlockTemplateLongPoll(s, request.LongPollID,
1937 useCoinbaseValue, closeChan)
1940 // Protect concurrent access when updating block templates.
1941 state := s.gbtWorkState
1943 defer state.Unlock()
1945 // Get and return a block template. A new block template will be
1946 // generated when the current best block has changed or the transactions
1947 // in the memory pool have been updated and it has been at least five
1948 // seconds since the last template was generated. Otherwise, the
1949 // timestamp for the existing block template is updated (and possibly
1950 // the difficulty on testnet per the consesus rules).
1951 if err := state.updateBlockTemplate(s, useCoinbaseValue); err != nil {
1954 return state.blockTemplateResult(useCoinbaseValue, nil)
1957 // chainErrToGBTErrString converts an error returned from btcchain to a string
1958 // which matches the reasons and format described in BIP0022 for rejection
1960 func chainErrToGBTErrString(err error) string {
1961 // When the passed error is not a RuleError, just return a generic
1962 // rejected string with the error text.
1963 ruleErr, ok := err.(blockchain.RuleError)
1965 return "rejected: " + err.Error()
1968 switch ruleErr.ErrorCode {
1969 case blockchain.ErrDuplicateBlock:
1971 case blockchain.ErrBlockTooBig:
1972 return "bad-block-size"
1973 case blockchain.ErrBlockVersionTooOld:
1974 return "bad-version"
1975 case blockchain.ErrInvalidTime:
1977 case blockchain.ErrTimeTooOld:
1978 return "time-too-old"
1979 case blockchain.ErrTimeTooNew:
1980 return "time-too-new"
1981 case blockchain.ErrDifficultyTooLow:
1982 return "bad-diffbits"
1983 case blockchain.ErrUnexpectedDifficulty:
1984 return "bad-diffbits"
1985 case blockchain.ErrHighHash:
1987 case blockchain.ErrBadMerkleRoot:
1988 return "bad-txnmrklroot"
1989 case blockchain.ErrBadCheckpoint:
1990 return "bad-checkpoint"
1991 case blockchain.ErrForkTooOld:
1992 return "fork-too-old"
1993 case blockchain.ErrCheckpointTimeTooOld:
1994 return "checkpoint-time-too-old"
1995 case blockchain.ErrNoTransactions:
1996 return "bad-txns-none"
1997 case blockchain.ErrTooManyTransactions:
1998 return "bad-txns-toomany"
1999 case blockchain.ErrNoTxInputs:
2000 return "bad-txns-noinputs"
2001 case blockchain.ErrNoTxOutputs:
2002 return "bad-txns-nooutputs"
2003 case blockchain.ErrTxTooBig:
2004 return "bad-txns-size"
2005 case blockchain.ErrBadTxOutValue:
2006 return "bad-txns-outputvalue"
2007 case blockchain.ErrDuplicateTxInputs:
2008 return "bad-txns-dupinputs"
2009 case blockchain.ErrBadTxInput:
2010 return "bad-txns-badinput"
2011 case blockchain.ErrMissingTxOut:
2012 return "bad-txns-missinginput"
2013 case blockchain.ErrUnfinalizedTx:
2014 return "bad-txns-unfinalizedtx"
2015 case blockchain.ErrDuplicateTx:
2016 return "bad-txns-duplicate"
2017 case blockchain.ErrOverwriteTx:
2018 return "bad-txns-overwrite"
2019 case blockchain.ErrImmatureSpend:
2020 return "bad-txns-maturity"
2021 case blockchain.ErrSpendTooHigh:
2022 return "bad-txns-highspend"
2023 case blockchain.ErrBadFees:
2024 return "bad-txns-fees"
2025 case blockchain.ErrTooManySigOps:
2026 return "high-sigops"
2027 case blockchain.ErrFirstTxNotCoinbase:
2028 return "bad-txns-nocoinbase"
2029 case blockchain.ErrMultipleCoinbases:
2030 return "bad-txns-multicoinbase"
2031 case blockchain.ErrBadCoinbaseScriptLen:
2032 return "bad-cb-length"
2033 case blockchain.ErrBadCoinbaseValue:
2034 return "bad-cb-value"
2035 case blockchain.ErrMissingCoinbaseHeight:
2036 return "bad-cb-height"
2037 case blockchain.ErrBadCoinbaseHeight:
2038 return "bad-cb-height"
2039 case blockchain.ErrScriptMalformed:
2040 return "bad-script-malformed"
2041 case blockchain.ErrScriptValidation:
2042 return "bad-script-validate"
2045 return "rejected: " + err.Error()
2048 // handleGetBlockTemplateProposal is a helper for handleGetBlockTemplate which
2049 // deals with block proposals.
2051 // See https://en.bitcoin.it/wiki/BIP_0023 for more details.
2052 func handleGetBlockTemplateProposal(s *rpcServer, request *btcjson.TemplateRequest) (interface{}, error) {
2053 hexData := request.Data
2055 return false, &btcjson.RPCError{
2056 Code: btcjson.ErrRPCType,
2057 Message: fmt.Sprintf("Data must contain the " +
2058 "hex-encoded serialized block that is being " +
2063 // Ensure the provided data is sane and deserialize the proposed block.
2064 if len(hexData)%2 != 0 {
2065 hexData = "0" + hexData
2067 dataBytes, err := hex.DecodeString(hexData)
2069 return false, &btcjson.RPCError{
2070 Code: btcjson.ErrRPCDeserialization,
2071 Message: fmt.Sprintf("Data must be "+
2072 "hexadecimal string (not %q)", hexData),
2075 var msgBlock wire.MsgBlock
2076 if err := msgBlock.Deserialize(bytes.NewReader(dataBytes)); err != nil {
2077 return nil, &btcjson.RPCError{
2078 Code: btcjson.ErrRPCDeserialization,
2079 Message: "Block decode failed: " + err.Error(),
2082 block := btcutil.NewBlock(&msgBlock)
2084 // Ensure the block is building from the expected previous block.
2085 expectedPrevHash := s.cfg.Chain.BestSnapshot().Hash
2086 prevHash := &block.MsgBlock().Header.PrevBlock
2087 if !expectedPrevHash.IsEqual(prevHash) {
2088 return "bad-prevblk", nil
2091 flags := blockchain.BFDryRun | blockchain.BFNoPoWCheck
2092 isOrphan, err := s.cfg.SyncMgr.SubmitBlock(block, flags)
2094 if _, ok := err.(blockchain.RuleError); !ok {
2095 errStr := fmt.Sprintf("Failed to process block proposal: %v", err)
2096 rpcsLog.Error(errStr)
2097 return nil, &btcjson.RPCError{
2098 Code: btcjson.ErrRPCVerify,
2103 rpcsLog.Infof("Rejected block proposal: %v", err)
2104 return chainErrToGBTErrString(err), nil
2107 return "orphan", nil
2113 // handleGetBlockTemplate implements the getblocktemplate command.
2115 // See https://en.bitcoin.it/wiki/BIP_0022 and
2116 // https://en.bitcoin.it/wiki/BIP_0023 for more details.
2117 func handleGetBlockTemplate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2118 c := cmd.(*btcjson.GetBlockTemplateCmd)
2119 request := c.Request
2121 // Set the default mode and override it if supplied.
2123 if request != nil && request.Mode != "" {
2129 return handleGetBlockTemplateRequest(s, request, closeChan)
2131 return handleGetBlockTemplateProposal(s, request)
2134 return nil, &btcjson.RPCError{
2135 Code: btcjson.ErrRPCInvalidParameter,
2136 Message: "Invalid mode",
2140 // handleGetConnectionCount implements the getconnectioncount command.
2141 func handleGetConnectionCount(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2142 return s.cfg.ConnMgr.ConnectedCount(), nil
2145 // handleGetCurrentNet implements the getcurrentnet command.
2146 func handleGetCurrentNet(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2147 return s.cfg.ChainParams.Net, nil
2150 // handleGetDifficulty implements the getdifficulty command.
2151 func handleGetDifficulty(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2152 best := s.cfg.Chain.BestSnapshot()
2153 return getDifficultyRatio(best.Bits, s.cfg.ChainParams), nil
2156 // handleGetGenerate implements the getgenerate command.
2157 func handleGetGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2158 return s.cfg.CPUMiner.IsMining(), nil
2161 // handleGetHashesPerSec implements the gethashespersec command.
2162 func handleGetHashesPerSec(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2163 return int64(s.cfg.CPUMiner.HashesPerSecond()), nil
2166 // handleGetHeaders implements the getheaders command.
2168 // NOTE: This is a btcsuite extension originally ported from
2169 // github.com/decred/dcrd.
2170 func handleGetHeaders(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2171 c := cmd.(*btcjson.GetHeadersCmd)
2173 // Fetch the requested headers from chain while respecting the provided
2174 // block locators and stop hash.
2175 blockLocators := make([]*chainhash.Hash, len(c.BlockLocators))
2176 for i := range c.BlockLocators {
2177 blockLocator, err := chainhash.NewHashFromStr(c.BlockLocators[i])
2179 return nil, rpcDecodeHexError(c.BlockLocators[i])
2181 blockLocators[i] = blockLocator
2183 var hashStop chainhash.Hash
2184 if c.HashStop != "" {
2185 err := chainhash.Decode(&hashStop, c.HashStop)
2187 return nil, rpcDecodeHexError(c.HashStop)
2190 headers := s.cfg.SyncMgr.LocateHeaders(blockLocators, &hashStop)
2192 // Return the serialized block headers as hex-encoded strings.
2193 hexBlockHeaders := make([]string, len(headers))
2194 var buf bytes.Buffer
2195 for i, h := range headers {
2196 err := h.Serialize(&buf)
2198 return nil, internalRPCError(err.Error(),
2199 "Failed to serialize block header")
2201 hexBlockHeaders[i] = hex.EncodeToString(buf.Bytes())
2204 return hexBlockHeaders, nil
2207 // handleGetInfo implements the getinfo command. We only return the fields
2208 // that are not related to wallet functionality.
2209 func handleGetInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2210 best := s.cfg.Chain.BestSnapshot()
2211 ret := &btcjson.InfoChainResult{
2212 Version: int32(1000000*appMajor + 10000*appMinor + 100*appPatch),
2213 ProtocolVersion: int32(maxProtocolVersion),
2214 Blocks: best.Height,
2215 TimeOffset: int64(s.cfg.TimeSource.Offset().Seconds()),
2216 Connections: s.cfg.ConnMgr.ConnectedCount(),
2218 Difficulty: getDifficultyRatio(best.Bits, s.cfg.ChainParams),
2219 TestNet: cfg.TestNet3,
2220 RelayFee: cfg.minRelayTxFee.ToBTC(),
2226 // handleGetMempoolInfo implements the getmempoolinfo command.
2227 func handleGetMempoolInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2228 mempoolTxns := s.cfg.TxMemPool.TxDescs()
2231 for _, txD := range mempoolTxns {
2232 numBytes += int64(txD.Tx.MsgTx().SerializeSize())
2235 ret := &btcjson.GetMempoolInfoResult{
2236 Size: int64(len(mempoolTxns)),
2243 // handleGetMiningInfo implements the getmininginfo command. We only return the
2244 // fields that are not related to wallet functionality.
2245 func handleGetMiningInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2246 // Create a default getnetworkhashps command to use defaults and make
2247 // use of the existing getnetworkhashps handler.
2248 gnhpsCmd := btcjson.NewGetNetworkHashPSCmd(nil, nil)
2249 networkHashesPerSecIface, err := handleGetNetworkHashPS(s, gnhpsCmd,
2254 networkHashesPerSec, ok := networkHashesPerSecIface.(int64)
2256 return nil, &btcjson.RPCError{
2257 Code: btcjson.ErrRPCInternal.Code,
2258 Message: "networkHashesPerSec is not an int64",
2262 best := s.cfg.Chain.BestSnapshot()
2263 result := btcjson.GetMiningInfoResult{
2264 Blocks: int64(best.Height),
2265 CurrentBlockSize: best.BlockSize,
2266 CurrentBlockWeight: best.BlockWeight,
2267 CurrentBlockTx: best.NumTxns,
2268 Difficulty: getDifficultyRatio(best.Bits, s.cfg.ChainParams),
2269 Generate: s.cfg.CPUMiner.IsMining(),
2270 GenProcLimit: s.cfg.CPUMiner.NumWorkers(),
2271 HashesPerSec: int64(s.cfg.CPUMiner.HashesPerSecond()),
2272 NetworkHashPS: networkHashesPerSec,
2273 PooledTx: uint64(s.cfg.TxMemPool.Count()),
2274 TestNet: cfg.TestNet3,
2279 // handleGetNetTotals implements the getnettotals command.
2280 func handleGetNetTotals(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2281 totalBytesRecv, totalBytesSent := s.cfg.ConnMgr.NetTotals()
2282 reply := &btcjson.GetNetTotalsResult{
2283 TotalBytesRecv: totalBytesRecv,
2284 TotalBytesSent: totalBytesSent,
2285 TimeMillis: time.Now().UTC().UnixNano() / int64(time.Millisecond),
2290 // handleGetNetworkHashPS implements the getnetworkhashps command.
2291 func handleGetNetworkHashPS(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2292 // Note: All valid error return paths should return an int64.
2293 // Literal zeros are inferred as int, and won't coerce to int64
2294 // because the return value is an interface{}.
2296 c := cmd.(*btcjson.GetNetworkHashPSCmd)
2298 // When the passed height is too high or zero, just return 0 now
2299 // since we can't reasonably calculate the number of network hashes
2300 // per second from invalid values. When it's negative, use the current
2301 // best block height.
2302 best := s.cfg.Chain.BestSnapshot()
2303 endHeight := int32(-1)
2304 if c.Height != nil {
2305 endHeight = int32(*c.Height)
2307 if endHeight > best.Height || endHeight == 0 {
2308 return int64(0), nil
2311 endHeight = best.Height
2314 // Calculate the number of blocks per retarget interval based on the
2315 // chain parameters.
2316 blocksPerRetarget := int32(s.cfg.ChainParams.TargetTimespan /
2317 s.cfg.ChainParams.TargetTimePerBlock)
2319 // Calculate the starting block height based on the passed number of
2320 // blocks. When the passed value is negative, use the last block the
2321 // difficulty changed as the starting height. Also make sure the
2322 // starting height is not before the beginning of the chain.
2323 numBlocks := int32(120)
2324 if c.Blocks != nil {
2325 numBlocks = int32(*c.Blocks)
2327 var startHeight int32
2329 startHeight = endHeight - ((endHeight % blocksPerRetarget) + 1)
2331 startHeight = endHeight - numBlocks
2333 if startHeight < 0 {
2336 rpcsLog.Debugf("Calculating network hashes per second from %d to %d",
2337 startHeight, endHeight)
2339 // Find the min and max block timestamps as well as calculate the total
2340 // amount of work that happened between the start and end blocks.
2341 var minTimestamp, maxTimestamp time.Time
2342 totalWork := big.NewInt(0)
2343 for curHeight := startHeight; curHeight <= endHeight; curHeight++ {
2344 hash, err := s.cfg.Chain.BlockHashByHeight(curHeight)
2346 context := "Failed to fetch block hash"
2347 return nil, internalRPCError(err.Error(), context)
2350 // Fetch the header from chain.
2351 header, err := s.cfg.Chain.FetchHeader(hash)
2353 context := "Failed to fetch block header"
2354 return nil, internalRPCError(err.Error(), context)
2357 if curHeight == startHeight {
2358 minTimestamp = header.Timestamp
2359 maxTimestamp = minTimestamp
2361 totalWork.Add(totalWork, blockchain.CalcWork(header.Bits))
2363 if minTimestamp.After(header.Timestamp) {
2364 minTimestamp = header.Timestamp
2366 if maxTimestamp.Before(header.Timestamp) {
2367 maxTimestamp = header.Timestamp
2372 // Calculate the difference in seconds between the min and max block
2373 // timestamps and avoid division by zero in the case where there is no
2375 timeDiff := int64(maxTimestamp.Sub(minTimestamp) / time.Second)
2377 return int64(0), nil
2380 hashesPerSec := new(big.Int).Div(totalWork, big.NewInt(timeDiff))
2381 return hashesPerSec.Int64(), nil
2384 // handleGetPeerInfo implements the getpeerinfo command.
2385 func handleGetPeerInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2386 peers := s.cfg.ConnMgr.ConnectedPeers()
2387 syncPeerID := s.cfg.SyncMgr.SyncPeerID()
2388 infos := make([]*btcjson.GetPeerInfoResult, 0, len(peers))
2389 for _, p := range peers {
2390 statsSnap := p.ToPeer().StatsSnapshot()
2391 info := &btcjson.GetPeerInfoResult{
2393 Addr: statsSnap.Addr,
2394 AddrLocal: p.ToPeer().LocalAddr().String(),
2395 Services: fmt.Sprintf("%08d", uint64(statsSnap.Services)),
2396 RelayTxes: !p.IsTxRelayDisabled(),
2397 LastSend: statsSnap.LastSend.Unix(),
2398 LastRecv: statsSnap.LastRecv.Unix(),
2399 BytesSent: statsSnap.BytesSent,
2400 BytesRecv: statsSnap.BytesRecv,
2401 ConnTime: statsSnap.ConnTime.Unix(),
2402 PingTime: float64(statsSnap.LastPingMicros),
2403 TimeOffset: statsSnap.TimeOffset,
2404 Version: statsSnap.Version,
2405 SubVer: statsSnap.UserAgent,
2406 Inbound: statsSnap.Inbound,
2407 StartingHeight: statsSnap.StartingHeight,
2408 CurrentHeight: statsSnap.LastBlock,
2409 BanScore: int32(p.BanScore()),
2410 FeeFilter: p.FeeFilter(),
2411 SyncNode: statsSnap.ID == syncPeerID,
2413 if p.ToPeer().LastPingNonce() != 0 {
2414 wait := float64(time.Since(statsSnap.LastPingTime).Nanoseconds())
2415 // We actually want microseconds.
2416 info.PingWait = wait / 1000
2418 infos = append(infos, info)
2423 // handleGetRawMempool implements the getrawmempool command.
2424 func handleGetRawMempool(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2425 c := cmd.(*btcjson.GetRawMempoolCmd)
2426 mp := s.cfg.TxMemPool
2428 if c.Verbose != nil && *c.Verbose {
2429 return mp.RawMempoolVerbose(), nil
2432 // The response is simply an array of the transaction hashes if the
2433 // verbose flag is not set.
2434 descs := mp.TxDescs()
2435 hashStrings := make([]string, len(descs))
2436 for i := range hashStrings {
2437 hashStrings[i] = descs[i].Tx.Hash().String()
2440 return hashStrings, nil
2443 // handleGetRawTransaction implements the getrawtransaction command.
2444 func handleGetRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2445 c := cmd.(*btcjson.GetRawTransactionCmd)
2447 // Convert the provided transaction hash hex to a Hash.
2448 txHash, err := chainhash.NewHashFromStr(c.Txid)
2450 return nil, rpcDecodeHexError(c.Txid)
2454 if c.Verbose != nil {
2455 verbose = *c.Verbose != 0
2458 // Try to fetch the transaction from the memory pool and if that fails,
2459 // try the block database.
2461 var blkHash *chainhash.Hash
2463 tx, err := s.cfg.TxMemPool.FetchTransaction(txHash)
2465 if s.cfg.TxIndex == nil {
2466 return nil, &btcjson.RPCError{
2467 Code: btcjson.ErrRPCNoTxInfo,
2468 Message: "The transaction index must be " +
2469 "enabled to query the blockchain " +
2470 "(specify --txindex)",
2474 // Look up the location of the transaction.
2475 blockRegion, err := s.cfg.TxIndex.TxBlockRegion(txHash)
2477 context := "Failed to retrieve transaction location"
2478 return nil, internalRPCError(err.Error(), context)
2480 if blockRegion == nil {
2481 return nil, rpcNoTxInfoError(txHash)
2484 // Load the raw transaction bytes from the database.
2486 err = s.cfg.DB.View(func(dbTx database.Tx) error {
2488 txBytes, err = dbTx.FetchBlockRegion(blockRegion)
2492 return nil, rpcNoTxInfoError(txHash)
2495 // When the verbose flag isn't set, simply return the serialized
2496 // transaction as a hex-encoded string. This is done here to
2497 // avoid deserializing it only to reserialize it again later.
2499 return hex.EncodeToString(txBytes), nil
2502 // Grab the block height.
2503 blkHash = blockRegion.Hash
2504 blkHeight, err = s.cfg.Chain.BlockHeightByHash(blkHash)
2506 context := "Failed to retrieve block height"
2507 return nil, internalRPCError(err.Error(), context)
2510 // Deserialize the transaction
2511 var msgTx wire.MsgTx
2512 err = msgTx.Deserialize(bytes.NewReader(txBytes))
2514 context := "Failed to deserialize transaction"
2515 return nil, internalRPCError(err.Error(), context)
2519 // When the verbose flag isn't set, simply return the
2520 // network-serialized transaction as a hex-encoded string.
2522 // Note that this is intentionally not directly
2523 // returning because the first return value is a
2524 // string and it would result in returning an empty
2525 // string to the client instead of nothing (nil) in the
2526 // case of an error.
2527 mtxHex, err := messageToHex(tx.MsgTx())
2537 // The verbose flag is set, so generate the JSON object and return it.
2538 var blkHeader *wire.BlockHeader
2539 var blkHashStr string
2540 var chainHeight int32
2542 // Fetch the header from chain.
2543 header, err := s.cfg.Chain.FetchHeader(blkHash)
2545 context := "Failed to fetch block header"
2546 return nil, internalRPCError(err.Error(), context)
2550 blkHashStr = blkHash.String()
2551 chainHeight = s.cfg.Chain.BestSnapshot().Height
2554 rawTxn, err := createTxRawResult(s.cfg.ChainParams, mtx, txHash.String(),
2555 blkHeader, blkHashStr, blkHeight, chainHeight)
2562 // handleGetTxOut handles gettxout commands.
2563 func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2564 c := cmd.(*btcjson.GetTxOutCmd)
2566 // Convert the provided transaction hash hex to a Hash.
2567 txHash, err := chainhash.NewHashFromStr(c.Txid)
2569 return nil, rpcDecodeHexError(c.Txid)
2572 // If requested and the tx is available in the mempool try to fetch it
2573 // from there, otherwise attempt to fetch from the block database.
2574 var bestBlockHash string
2575 var confirmations int32
2580 includeMempool := true
2581 if c.IncludeMempool != nil {
2582 includeMempool = *c.IncludeMempool
2584 // TODO: This is racy. It should attempt to fetch it directly and check
2586 if includeMempool && s.cfg.TxMemPool.HaveTransaction(txHash) {
2587 tx, err := s.cfg.TxMemPool.FetchTransaction(txHash)
2589 return nil, rpcNoTxInfoError(txHash)
2593 if c.Vout > uint32(len(mtx.TxOut)-1) {
2594 return nil, &btcjson.RPCError{
2595 Code: btcjson.ErrRPCInvalidTxVout,
2596 Message: "Output index number (vout) does not " +
2597 "exist for transaction.",
2601 txOut := mtx.TxOut[c.Vout]
2603 errStr := fmt.Sprintf("Output index: %d for txid: %s "+
2604 "does not exist", c.Vout, txHash)
2605 return nil, internalRPCError(errStr, "")
2608 best := s.cfg.Chain.BestSnapshot()
2609 bestBlockHash = best.Hash.String()
2611 txVersion = mtx.Version
2613 pkScript = txOut.PkScript
2614 isCoinbase = blockchain.IsCoinBaseTx(mtx)
2616 entry, err := s.cfg.Chain.FetchUtxoEntry(txHash)
2618 return nil, rpcNoTxInfoError(txHash)
2621 // To match the behavior of the reference client, return nil
2622 // (JSON null) if the transaction output is spent by another
2623 // transaction already in the main chain. Mined transactions
2624 // that are spent by a mempool transaction are not affected by
2626 if entry == nil || entry.IsOutputSpent(c.Vout) {
2630 best := s.cfg.Chain.BestSnapshot()
2631 bestBlockHash = best.Hash.String()
2632 confirmations = 1 + best.Height - entry.BlockHeight()
2633 txVersion = entry.Version()
2634 value = entry.AmountByIndex(c.Vout)
2635 pkScript = entry.PkScriptByIndex(c.Vout)
2636 isCoinbase = entry.IsCoinBase()
2639 // Disassemble script into single line printable format.
2640 // The disassembled string will contain [error] inline if the script
2641 // doesn't fully parse, so ignore the error here.
2642 disbuf, _ := txscript.DisasmString(pkScript)
2644 // Get further info about the script.
2645 // Ignore the error here since an error means the script couldn't parse
2646 // and there is no additional information about it anyways.
2647 scriptClass, addrs, reqSigs, _ := txscript.ExtractPkScriptAddrs(pkScript,
2649 addresses := make([]string, len(addrs))
2650 for i, addr := range addrs {
2651 addresses[i] = addr.EncodeAddress()
2654 txOutReply := &btcjson.GetTxOutResult{
2655 BestBlock: bestBlockHash,
2656 Confirmations: int64(confirmations),
2657 Value: btcutil.Amount(value).ToBTC(),
2659 ScriptPubKey: btcjson.ScriptPubKeyResult{
2661 Hex: hex.EncodeToString(pkScript),
2662 ReqSigs: int32(reqSigs),
2663 Type: scriptClass.String(),
2664 Addresses: addresses,
2666 Coinbase: isCoinbase,
2668 return txOutReply, nil
2671 // handleHelp implements the help command.
2672 func handleHelp(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2673 c := cmd.(*btcjson.HelpCmd)
2675 // Provide a usage overview of all commands when no specific command
2678 if c.Command != nil {
2679 command = *c.Command
2682 usage, err := s.helpCacher.rpcUsage(false)
2684 context := "Failed to generate RPC usage"
2685 return nil, internalRPCError(err.Error(), context)
2690 // Check that the command asked for is supported and implemented. Only
2691 // search the main list of handlers since help should not be provided
2692 // for commands that are unimplemented or related to wallet
2694 if _, ok := rpcHandlers[command]; !ok {
2695 return nil, &btcjson.RPCError{
2696 Code: btcjson.ErrRPCInvalidParameter,
2697 Message: "Unknown command: " + command,
2701 // Get the help for the command.
2702 help, err := s.helpCacher.rpcMethodHelp(command)
2704 context := "Failed to generate help"
2705 return nil, internalRPCError(err.Error(), context)
2710 // handlePing implements the ping command.
2711 func handlePing(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2712 // Ask server to ping \o_
2713 nonce, err := wire.RandomUint64()
2715 return nil, internalRPCError("Not sending ping - failed to "+
2716 "generate nonce: "+err.Error(), "")
2718 s.cfg.ConnMgr.BroadcastMessage(wire.NewMsgPing(nonce))
2723 // retrievedTx represents a transaction that was either loaded from the
2724 // transaction memory pool or from the database. When a transaction is loaded
2725 // from the database, it is loaded with the raw serialized bytes while the
2726 // mempool has the fully deserialized structure. This structure therefore will
2727 // have one of the two fields set depending on where is was retrieved from.
2728 // This is mainly done for efficiency to avoid extra serialization steps when
2730 type retrievedTx struct {
2732 blkHash *chainhash.Hash // Only set when transaction is in a block.
2736 // fetchInputTxos fetches the outpoints from all transactions referenced by the
2737 // inputs to the passed transaction by checking the transaction mempool first
2738 // then the transaction index for those already mined into blocks.
2739 func fetchInputTxos(s *rpcServer, tx *wire.MsgTx) (map[wire.OutPoint]wire.TxOut, error) {
2740 mp := s.cfg.TxMemPool
2741 originOutputs := make(map[wire.OutPoint]wire.TxOut)
2742 for txInIndex, txIn := range tx.TxIn {
2743 // Attempt to fetch and use the referenced transaction from the
2745 origin := &txIn.PreviousOutPoint
2746 originTx, err := mp.FetchTransaction(&origin.Hash)
2748 txOuts := originTx.MsgTx().TxOut
2749 if origin.Index >= uint32(len(txOuts)) {
2750 errStr := fmt.Sprintf("unable to find output "+
2751 "%v referenced from transaction %s:%d",
2752 origin, tx.TxHash(), txInIndex)
2753 return nil, internalRPCError(errStr, "")
2756 originOutputs[*origin] = *txOuts[origin.Index]
2760 // Look up the location of the transaction.
2761 blockRegion, err := s.cfg.TxIndex.TxBlockRegion(&origin.Hash)
2763 context := "Failed to retrieve transaction location"
2764 return nil, internalRPCError(err.Error(), context)
2766 if blockRegion == nil {
2767 return nil, rpcNoTxInfoError(&origin.Hash)
2770 // Load the raw transaction bytes from the database.
2772 err = s.cfg.DB.View(func(dbTx database.Tx) error {
2774 txBytes, err = dbTx.FetchBlockRegion(blockRegion)
2778 return nil, rpcNoTxInfoError(&origin.Hash)
2781 // Deserialize the transaction
2782 var msgTx wire.MsgTx
2783 err = msgTx.Deserialize(bytes.NewReader(txBytes))
2785 context := "Failed to deserialize transaction"
2786 return nil, internalRPCError(err.Error(), context)
2789 // Add the referenced output to the map.
2790 if origin.Index >= uint32(len(msgTx.TxOut)) {
2791 errStr := fmt.Sprintf("unable to find output %v "+
2792 "referenced from transaction %s:%d", origin,
2793 tx.TxHash(), txInIndex)
2794 return nil, internalRPCError(errStr, "")
2796 originOutputs[*origin] = *msgTx.TxOut[origin.Index]
2799 return originOutputs, nil
2802 // createVinListPrevOut returns a slice of JSON objects for the inputs of the
2803 // passed transaction.
2804 func createVinListPrevOut(s *rpcServer, mtx *wire.MsgTx, chainParams *chaincfg.Params, vinExtra bool, filterAddrMap map[string]struct{}) ([]btcjson.VinPrevOut, error) {
2805 // Coinbase transactions only have a single txin by definition.
2806 if blockchain.IsCoinBaseTx(mtx) {
2807 // Only include the transaction if the filter map is empty
2808 // because a coinbase input has no addresses and so would never
2809 // match a non-empty filter.
2810 if len(filterAddrMap) != 0 {
2815 vinList := make([]btcjson.VinPrevOut, 1)
2816 vinList[0].Coinbase = hex.EncodeToString(txIn.SignatureScript)
2817 vinList[0].Sequence = txIn.Sequence
2821 // Use a dynamically sized list to accommodate the address filter.
2822 vinList := make([]btcjson.VinPrevOut, 0, len(mtx.TxIn))
2824 // Lookup all of the referenced transaction outputs needed to populate
2825 // the previous output information if requested.
2826 var originOutputs map[wire.OutPoint]wire.TxOut
2827 if vinExtra || len(filterAddrMap) > 0 {
2829 originOutputs, err = fetchInputTxos(s, mtx)
2835 for _, txIn := range mtx.TxIn {
2836 // The disassembled string will contain [error] inline
2837 // if the script doesn't fully parse, so ignore the
2839 disbuf, _ := txscript.DisasmString(txIn.SignatureScript)
2841 // Create the basic input entry without the additional optional
2842 // previous output details which will be added later if
2843 // requested and available.
2844 prevOut := &txIn.PreviousOutPoint
2845 vinEntry := btcjson.VinPrevOut{
2846 Txid: prevOut.Hash.String(),
2847 Vout: prevOut.Index,
2848 Sequence: txIn.Sequence,
2849 ScriptSig: &btcjson.ScriptSig{
2851 Hex: hex.EncodeToString(txIn.SignatureScript),
2855 if len(txIn.Witness) != 0 {
2856 vinEntry.Witness = witnessToHex(txIn.Witness)
2859 // Add the entry to the list now if it already passed the filter
2860 // since the previous output might not be available.
2861 passesFilter := len(filterAddrMap) == 0
2863 vinList = append(vinList, vinEntry)
2866 // Only populate previous output information if requested and
2868 if len(originOutputs) == 0 {
2871 originTxOut, ok := originOutputs[*prevOut]
2876 // Ignore the error here since an error means the script
2877 // couldn't parse and there is no additional information about
2879 _, addrs, _, _ := txscript.ExtractPkScriptAddrs(
2880 originTxOut.PkScript, chainParams)
2882 // Encode the addresses while checking if the address passes the
2883 // filter when needed.
2884 encodedAddrs := make([]string, len(addrs))
2885 for j, addr := range addrs {
2886 encodedAddr := addr.EncodeAddress()
2887 encodedAddrs[j] = encodedAddr
2889 // No need to check the map again if the filter already
2894 if _, exists := filterAddrMap[encodedAddr]; exists {
2899 // Ignore the entry if it doesn't pass the filter.
2904 // Add entry to the list if it wasn't already done above.
2905 if len(filterAddrMap) != 0 {
2906 vinList = append(vinList, vinEntry)
2909 // Update the entry with previous output information if
2912 vinListEntry := &vinList[len(vinList)-1]
2913 vinListEntry.PrevOut = &btcjson.PrevOut{
2914 Addresses: encodedAddrs,
2915 Value: btcutil.Amount(originTxOut.Value).ToBTC(),
2923 // fetchMempoolTxnsForAddress queries the address index for all unconfirmed
2924 // transactions that involve the provided address. The results will be limited
2925 // by the number to skip and the number requested.
2926 func fetchMempoolTxnsForAddress(s *rpcServer, addr btcutil.Address, numToSkip, numRequested uint32) ([]*btcutil.Tx, uint32) {
2927 // There are no entries to return when there are less available than the
2928 // number being skipped.
2929 mpTxns := s.cfg.AddrIndex.UnconfirmedTxnsForAddress(addr)
2930 numAvailable := uint32(len(mpTxns))
2931 if numToSkip > numAvailable {
2932 return nil, numAvailable
2935 // Filter the available entries based on the number to skip and number
2937 rangeEnd := numToSkip + numRequested
2938 if rangeEnd > numAvailable {
2939 rangeEnd = numAvailable
2941 return mpTxns[numToSkip:rangeEnd], numToSkip
2944 // handleSearchRawTransactions implements the searchrawtransactions command.
2945 func handleSearchRawTransactions(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
2946 // Respond with an error if the address index is not enabled.
2947 addrIndex := s.cfg.AddrIndex
2948 if addrIndex == nil {
2949 return nil, &btcjson.RPCError{
2950 Code: btcjson.ErrRPCMisc,
2951 Message: "Address index must be enabled (--addrindex)",
2955 // Override the flag for including extra previous output information in
2956 // each input if needed.
2957 c := cmd.(*btcjson.SearchRawTransactionsCmd)
2959 if c.VinExtra != nil {
2960 vinExtra = *c.VinExtra != 0
2963 // Including the extra previous output information requires the
2964 // transaction index. Currently the address index relies on the
2965 // transaction index, so this check is redundant, but it's better to be
2966 // safe in case the address index is ever changed to not rely on it.
2967 if vinExtra && s.cfg.TxIndex == nil {
2968 return nil, &btcjson.RPCError{
2969 Code: btcjson.ErrRPCMisc,
2970 Message: "Transaction index must be enabled (--txindex)",
2974 // Attempt to decode the supplied address.
2975 params := s.cfg.ChainParams
2976 addr, err := btcutil.DecodeAddress(c.Address, params)
2978 return nil, &btcjson.RPCError{
2979 Code: btcjson.ErrRPCInvalidAddressOrKey,
2980 Message: "Invalid address or key: " + err.Error(),
2984 // Override the default number of requested entries if needed. Also,
2985 // just return now if the number of requested entries is zero to avoid
2989 numRequested = *c.Count
2990 if numRequested < 0 {
2994 if numRequested == 0 {
2998 // Override the default number of entries to skip if needed.
3007 // Override the reverse flag if needed.
3009 if c.Reverse != nil {
3010 reverse = *c.Reverse
3013 // Add transactions from mempool first if client asked for reverse
3014 // order. Otherwise, they will be added last (as needed depending on
3015 // the requested counts).
3017 // NOTE: This code doesn't sort by dependency. This might be something
3018 // to do in the future for the client's convenience, or leave it to the
3020 numSkipped := uint32(0)
3021 addressTxns := make([]retrievedTx, 0, numRequested)
3023 // Transactions in the mempool are not in a block header yet,
3024 // so the block header field in the retieved transaction struct
3026 mpTxns, mpSkipped := fetchMempoolTxnsForAddress(s, addr,
3027 uint32(numToSkip), uint32(numRequested))
3028 numSkipped += mpSkipped
3029 for _, tx := range mpTxns {
3030 addressTxns = append(addressTxns, retrievedTx{tx: tx})
3034 // Fetch transactions from the database in the desired order if more are
3036 if len(addressTxns) < numRequested {
3037 err = s.cfg.DB.View(func(dbTx database.Tx) error {
3038 regions, dbSkipped, err := addrIndex.TxRegionsForAddress(
3039 dbTx, addr, uint32(numToSkip)-numSkipped,
3040 uint32(numRequested-len(addressTxns)), reverse)
3045 // Load the raw transaction bytes from the database.
3046 serializedTxns, err := dbTx.FetchBlockRegions(regions)
3051 // Add the transaction and the hash of the block it is
3052 // contained in to the list. Note that the transaction
3053 // is left serialized here since the caller might have
3054 // requested non-verbose output and hence there would be
3055 // no point in deserializing it just to reserialize it
3057 for i, serializedTx := range serializedTxns {
3058 addressTxns = append(addressTxns, retrievedTx{
3059 txBytes: serializedTx,
3060 blkHash: regions[i].Hash,
3063 numSkipped += dbSkipped
3068 context := "Failed to load address index entries"
3069 return nil, internalRPCError(err.Error(), context)
3074 // Add transactions from mempool last if client did not request reverse
3075 // order and the number of results is still under the number requested.
3076 if !reverse && len(addressTxns) < numRequested {
3077 // Transactions in the mempool are not in a block header yet,
3078 // so the block header field in the retieved transaction struct
3080 mpTxns, mpSkipped := fetchMempoolTxnsForAddress(s, addr,
3081 uint32(numToSkip)-numSkipped, uint32(numRequested-
3083 numSkipped += mpSkipped
3084 for _, tx := range mpTxns {
3085 addressTxns = append(addressTxns, retrievedTx{tx: tx})
3089 // Address has never been used if neither source yielded any results.
3090 if len(addressTxns) == 0 {
3091 return nil, &btcjson.RPCError{
3092 Code: btcjson.ErrRPCNoTxInfo,
3093 Message: "No information available about address",
3097 // Serialize all of the transactions to hex.
3098 hexTxns := make([]string, len(addressTxns))
3099 for i := range addressTxns {
3100 // Simply encode the raw bytes to hex when the retrieved
3101 // transaction is already in serialized form.
3102 rtx := &addressTxns[i]
3103 if rtx.txBytes != nil {
3104 hexTxns[i] = hex.EncodeToString(rtx.txBytes)
3108 // Serialize the transaction first and convert to hex when the
3109 // retrieved transaction is the deserialized structure.
3110 hexTxns[i], err = messageToHex(rtx.tx.MsgTx())
3116 // When not in verbose mode, simply return a list of serialized txns.
3117 if c.Verbose != nil && *c.Verbose == 0 {
3121 // Normalize the provided filter addresses (if any) to ensure there are
3123 filterAddrMap := make(map[string]struct{})
3124 if c.FilterAddrs != nil && len(*c.FilterAddrs) > 0 {
3125 for _, addr := range *c.FilterAddrs {
3126 filterAddrMap[addr] = struct{}{}
3130 // The verbose flag is set, so generate the JSON object and return it.
3131 best := s.cfg.Chain.BestSnapshot()
3132 srtList := make([]btcjson.SearchRawTransactionsResult, len(addressTxns))
3133 for i := range addressTxns {
3134 // The deserialized transaction is needed, so deserialize the
3135 // retrieved transaction if it's in serialized form (which will
3136 // be the case when it was lookup up from the database).
3137 // Otherwise, use the existing deserialized transaction.
3138 rtx := &addressTxns[i]
3141 // Deserialize the transaction.
3142 mtx = new(wire.MsgTx)
3143 err := mtx.Deserialize(bytes.NewReader(rtx.txBytes))
3145 context := "Failed to deserialize transaction"
3146 return nil, internalRPCError(err.Error(),
3150 mtx = rtx.tx.MsgTx()
3153 result := &srtList[i]
3154 result.Hex = hexTxns[i]
3155 result.Txid = mtx.TxHash().String()
3156 result.Vin, err = createVinListPrevOut(s, mtx, params, vinExtra,
3161 result.Vout = createVoutList(mtx, params, filterAddrMap)
3162 result.Version = mtx.Version
3163 result.LockTime = mtx.LockTime
3165 // Transactions grabbed from the mempool aren't yet in a block,
3166 // so conditionally fetch block details here. This will be
3167 // reflected in the final JSON output (mempool won't have
3168 // confirmations or block information).
3169 var blkHeader *wire.BlockHeader
3170 var blkHashStr string
3172 if blkHash := rtx.blkHash; blkHash != nil {
3173 // Fetch the header from chain.
3174 header, err := s.cfg.Chain.FetchHeader(blkHash)
3176 return nil, &btcjson.RPCError{
3177 Code: btcjson.ErrRPCBlockNotFound,
3178 Message: "Block not found",
3182 // Get the block height from chain.
3183 height, err := s.cfg.Chain.BlockHeightByHash(blkHash)
3185 context := "Failed to obtain block height"
3186 return nil, internalRPCError(err.Error(), context)
3190 blkHashStr = blkHash.String()
3194 // Add the block information to the result if there is any.
3195 if blkHeader != nil {
3196 // This is not a typo, they are identical in Bitcoin
3198 result.Time = blkHeader.Timestamp.Unix()
3199 result.Blocktime = blkHeader.Timestamp.Unix()
3200 result.BlockHash = blkHashStr
3201 result.Confirmations = uint64(1 + best.Height - blkHeight)
3208 // handleSendRawTransaction implements the sendrawtransaction command.
3209 func handleSendRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
3210 c := cmd.(*btcjson.SendRawTransactionCmd)
3211 // Deserialize and send off to tx relay
3213 if len(hexStr)%2 != 0 {
3214 hexStr = "0" + hexStr
3216 serializedTx, err := hex.DecodeString(hexStr)
3218 return nil, rpcDecodeHexError(hexStr)
3220 var msgTx wire.MsgTx
3221 err = msgTx.Deserialize(bytes.NewReader(serializedTx))
3223 return nil, &btcjson.RPCError{
3224 Code: btcjson.ErrRPCDeserialization,
3225 Message: "TX decode failed: " + err.Error(),
3229 // Use 0 for the tag to represent local node.
3230 tx := btcutil.NewTx(&msgTx)
3231 acceptedTxs, err := s.cfg.TxMemPool.ProcessTransaction(tx, false, false, 0)
3233 // When the error is a rule error, it means the transaction was
3234 // simply rejected as opposed to something actually going wrong,
3235 // so log it as such. Otherwise, something really did go wrong,
3236 // so log it as an actual error. In both cases, a JSON-RPC
3237 // error is returned to the client with the deserialization
3238 // error code (to match bitcoind behavior).
3239 if _, ok := err.(mempool.RuleError); ok {
3240 rpcsLog.Debugf("Rejected transaction %v: %v", tx.Hash(),
3243 rpcsLog.Errorf("Failed to process transaction %v: %v",
3246 return nil, &btcjson.RPCError{
3247 Code: btcjson.ErrRPCDeserialization,
3248 Message: "TX rejected: " + err.Error(),
3252 // When the transaction was accepted it should be the first item in the
3253 // returned array of accepted transactions. The only way this will not
3254 // be true is if the API for ProcessTransaction changes and this code is
3255 // not properly updated, but ensure the condition holds as a safeguard.
3257 // Also, since an error is being returned to the caller, ensure the
3258 // transaction is removed from the memory pool.
3259 if len(acceptedTxs) == 0 || !acceptedTxs[0].Tx.Hash().IsEqual(tx.Hash()) {
3260 s.cfg.TxMemPool.RemoveTransaction(tx, true)
3262 errStr := fmt.Sprintf("transaction %v is not in accepted list",
3264 return nil, internalRPCError(errStr, "")
3267 // Generate and relay inventory vectors for all newly accepted
3268 // transactions into the memory pool due to the original being
3270 s.cfg.ConnMgr.RelayTransactions(acceptedTxs)
3272 // Notify both websocket and getblocktemplate long poll clients of all
3273 // newly accepted transactions.
3274 s.NotifyNewTransactions(acceptedTxs)
3276 // Keep track of all the sendrawtransaction request txns so that they
3277 // can be rebroadcast if they don't make their way into a block.
3278 txD := acceptedTxs[0]
3279 iv := wire.NewInvVect(wire.InvTypeTx, txD.Tx.Hash())
3280 s.cfg.ConnMgr.AddRebroadcastInventory(iv, txD)
3282 return tx.Hash().String(), nil
3285 // handleSetGenerate implements the setgenerate command.
3286 func handleSetGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
3287 c := cmd.(*btcjson.SetGenerateCmd)
3289 // Disable generation regardless of the provided generate flag if the
3290 // maximum number of threads (goroutines for our purposes) is 0.
3291 // Otherwise enable or disable it depending on the provided flag.
3292 generate := c.Generate
3294 if c.GenProcLimit != nil {
3295 genProcLimit = *c.GenProcLimit
3297 if genProcLimit == 0 {
3302 s.cfg.CPUMiner.Stop()
3304 // Respond with an error if there are no addresses to pay the
3305 // created blocks to.
3306 if len(cfg.miningAddrs) == 0 {
3307 return nil, &btcjson.RPCError{
3308 Code: btcjson.ErrRPCInternal.Code,
3309 Message: "No payment addresses specified " +
3314 // It's safe to call start even if it's already started.
3315 s.cfg.CPUMiner.SetNumWorkers(int32(genProcLimit))
3316 s.cfg.CPUMiner.Start()
3321 // handleStop implements the stop command.
3322 func handleStop(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
3324 case s.requestProcessShutdown <- struct{}{}:
3327 return "btcd stopping.", nil
3330 // handleSubmitBlock implements the submitblock command.
3331 func handleSubmitBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
3332 c := cmd.(*btcjson.SubmitBlockCmd)
3334 // Deserialize the submitted block.
3335 hexStr := c.HexBlock
3336 if len(hexStr)%2 != 0 {
3337 hexStr = "0" + c.HexBlock
3339 serializedBlock, err := hex.DecodeString(hexStr)
3341 return nil, rpcDecodeHexError(hexStr)
3344 block, err := btcutil.NewBlockFromBytes(serializedBlock)
3346 return nil, &btcjson.RPCError{
3347 Code: btcjson.ErrRPCDeserialization,
3348 Message: "Block decode failed: " + err.Error(),
3352 // Process this block using the same rules as blocks coming from other
3353 // nodes. This will in turn relay it to the network like normal.
3354 _, err = s.cfg.SyncMgr.SubmitBlock(block, blockchain.BFNone)
3356 return fmt.Sprintf("rejected: %s", err.Error()), nil
3359 rpcsLog.Infof("Accepted block %s via submitblock", block.Hash())
3363 // handleUptime implements the uptime command.
3364 func handleUptime(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
3365 return time.Now().Unix() - s.cfg.StartupTime, nil
3368 // handleValidateAddress implements the validateaddress command.
3369 func handleValidateAddress(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
3370 c := cmd.(*btcjson.ValidateAddressCmd)
3372 result := btcjson.ValidateAddressChainResult{}
3373 addr, err := btcutil.DecodeAddress(c.Address, s.cfg.ChainParams)
3375 // Return the default value (false) for IsValid.
3379 result.Address = addr.EncodeAddress()
3380 result.IsValid = true
3385 func verifyChain(s *rpcServer, level, depth int32) error {
3386 best := s.cfg.Chain.BestSnapshot()
3387 finishHeight := best.Height - depth
3388 if finishHeight < 0 {
3391 rpcsLog.Infof("Verifying chain for %d blocks at level %d",
3392 best.Height-finishHeight, level)
3394 for height := best.Height; height > finishHeight; height-- {
3395 // Level 0 just looks up the block.
3396 block, err := s.cfg.Chain.BlockByHeight(height)
3398 rpcsLog.Errorf("Verify is unable to fetch block at "+
3399 "height %d: %v", height, err)
3403 // Level 1 does basic chain sanity checks.
3405 err := blockchain.CheckBlockSanity(block,
3406 s.cfg.ChainParams.PowLimit, s.cfg.TimeSource)
3408 rpcsLog.Errorf("Verify is unable to validate "+
3409 "block at hash %v height %d: %v",
3410 block.Hash(), height, err)
3415 rpcsLog.Infof("Chain verify completed successfully")
3420 // handleVerifyChain implements the verifychain command.
3421 func handleVerifyChain(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
3422 c := cmd.(*btcjson.VerifyChainCmd)
3424 var checkLevel, checkDepth int32
3425 if c.CheckLevel != nil {
3426 checkLevel = *c.CheckLevel
3428 if c.CheckDepth != nil {
3429 checkDepth = *c.CheckDepth
3432 err := verifyChain(s, checkLevel, checkDepth)
3433 return err == nil, nil
3436 // handleVerifyMessage implements the verifymessage command.
3437 func handleVerifyMessage(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
3438 c := cmd.(*btcjson.VerifyMessageCmd)
3440 // Decode the provided address.
3441 params := s.cfg.ChainParams
3442 addr, err := btcutil.DecodeAddress(c.Address, params)
3444 return nil, &btcjson.RPCError{
3445 Code: btcjson.ErrRPCInvalidAddressOrKey,
3446 Message: "Invalid address or key: " + err.Error(),
3450 // Only P2PKH addresses are valid for signing.
3451 if _, ok := addr.(*btcutil.AddressPubKeyHash); !ok {
3452 return nil, &btcjson.RPCError{
3453 Code: btcjson.ErrRPCType,
3454 Message: "Address is not a pay-to-pubkey-hash address",
3458 // Decode base64 signature.
3459 sig, err := base64.StdEncoding.DecodeString(c.Signature)
3461 return nil, &btcjson.RPCError{
3462 Code: btcjson.ErrRPCParse.Code,
3463 Message: "Malformed base64 encoding: " + err.Error(),
3467 // Validate the signature - this just shows that it was valid at all.
3468 // we will compare it with the key next.
3469 var buf bytes.Buffer
3470 wire.WriteVarString(&buf, 0, "Bitcoin Signed Message:\n")
3471 wire.WriteVarString(&buf, 0, c.Message)
3472 expectedMessageHash := chainhash.DoubleHashB(buf.Bytes())
3473 pk, wasCompressed, err := btcec.RecoverCompact(btcec.S256(), sig,
3474 expectedMessageHash)
3476 // Mirror Bitcoin Core behavior, which treats error in
3477 // RecoverCompact as invalid signature.
3481 // Reconstruct the pubkey hash.
3482 var serializedPK []byte
3484 serializedPK = pk.SerializeCompressed()
3486 serializedPK = pk.SerializeUncompressed()
3488 address, err := btcutil.NewAddressPubKey(serializedPK, params)
3490 // Again mirror Bitcoin Core behavior, which treats error in public key
3491 // reconstruction as invalid signature.
3495 // Return boolean if addresses match.
3496 return address.EncodeAddress() == c.Address, nil
3499 // handleVersion implements the version command.
3501 // NOTE: This is a btcsuite extension ported from github.com/decred/dcrd.
3502 func handleVersion(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
3503 result := map[string]btcjson.VersionResult{
3505 VersionString: jsonrpcSemverString,
3506 Major: jsonrpcSemverMajor,
3507 Minor: jsonrpcSemverMinor,
3508 Patch: jsonrpcSemverPatch,
3514 // rpcServer provides a concurrent safe RPC server to a chain server.
3515 type rpcServer struct {
3519 authsha [sha256.Size]byte
3520 limitauthsha [sha256.Size]byte
3521 ntfnMgr *wsNotificationManager
3523 statusLines map[int]string
3524 statusLock sync.RWMutex
3526 gbtWorkState *gbtWorkState
3527 helpCacher *helpCacher
3528 requestProcessShutdown chan struct{}
3532 // httpStatusLine returns a response Status-Line (RFC 2616 Section 6.1)
3533 // for the given request and response status code. This function was lifted and
3534 // adapted from the standard library HTTP server code since it's not exported.
3535 func (s *rpcServer) httpStatusLine(req *http.Request, code int) string {
3538 proto11 := req.ProtoAtLeast(1, 1)
3542 s.statusLock.RLock()
3543 line, ok := s.statusLines[key]
3544 s.statusLock.RUnlock()
3554 codeStr := strconv.Itoa(code)
3555 text := http.StatusText(code)
3557 line = proto + " " + codeStr + " " + text + "\r\n"
3559 s.statusLines[key] = line
3560 s.statusLock.Unlock()
3562 text = "status code " + codeStr
3563 line = proto + " " + codeStr + " " + text + "\r\n"
3569 // writeHTTPResponseHeaders writes the necessary response headers prior to
3570 // writing an HTTP body given a request to use for protocol negotiation, headers
3571 // to write, a status code, and a writer.
3572 func (s *rpcServer) writeHTTPResponseHeaders(req *http.Request, headers http.Header, code int, w io.Writer) error {
3573 _, err := io.WriteString(w, s.httpStatusLine(req, code))
3578 err = headers.Write(w)
3583 _, err = io.WriteString(w, "\r\n")
3587 // Stop is used by server.go to stop the rpc listener.
3588 func (s *rpcServer) Stop() error {
3589 if atomic.AddInt32(&s.shutdown, 1) != 1 {
3590 rpcsLog.Infof("RPC server is already in the process of shutting down")
3593 rpcsLog.Warnf("RPC server shutting down")
3594 for _, listener := range s.cfg.Listeners {
3595 err := listener.Close()
3597 rpcsLog.Errorf("Problem shutting down rpc: %v", err)
3601 s.ntfnMgr.Shutdown()
3602 s.ntfnMgr.WaitForShutdown()
3605 rpcsLog.Infof("RPC server shutdown complete")
3609 // RequestedProcessShutdown returns a channel that is sent to when an authorized
3610 // RPC client requests the process to shutdown. If the request can not be read
3611 // immediately, it is dropped.
3612 func (s *rpcServer) RequestedProcessShutdown() <-chan struct{} {
3613 return s.requestProcessShutdown
3616 // NotifyNewTransactions notifies both websocket and getblocktemplate long
3617 // poll clients of the passed transactions. This function should be called
3618 // whenever new transactions are added to the mempool.
3619 func (s *rpcServer) NotifyNewTransactions(txns []*mempool.TxDesc) {
3620 for _, txD := range txns {
3621 // Notify websocket clients about mempool transactions.
3622 s.ntfnMgr.NotifyMempoolTx(txD.Tx, true)
3624 // Potentially notify any getblocktemplate long poll clients
3625 // about stale block templates due to the new transaction.
3626 s.gbtWorkState.NotifyMempoolTx(s.cfg.TxMemPool.LastUpdated())
3630 // limitConnections responds with a 503 service unavailable and returns true if
3631 // adding another client would exceed the maximum allow RPC clients.
3633 // This function is safe for concurrent access.
3634 func (s *rpcServer) limitConnections(w http.ResponseWriter, remoteAddr string) bool {
3635 if int(atomic.LoadInt32(&s.numClients)+1) > cfg.RPCMaxClients {
3636 rpcsLog.Infof("Max RPC clients exceeded [%d] - "+
3637 "disconnecting client %s", cfg.RPCMaxClients,
3639 http.Error(w, "503 Too busy. Try again later.",
3640 http.StatusServiceUnavailable)
3646 // incrementClients adds one to the number of connected RPC clients. Note
3647 // this only applies to standard clients. Websocket clients have their own
3648 // limits and are tracked separately.
3650 // This function is safe for concurrent access.
3651 func (s *rpcServer) incrementClients() {
3652 atomic.AddInt32(&s.numClients, 1)
3655 // decrementClients subtracts one from the number of connected RPC clients.
3656 // Note this only applies to standard clients. Websocket clients have their own
3657 // limits and are tracked separately.
3659 // This function is safe for concurrent access.
3660 func (s *rpcServer) decrementClients() {
3661 atomic.AddInt32(&s.numClients, -1)
3664 // checkAuth checks the HTTP Basic authentication supplied by a wallet
3665 // or RPC client in the HTTP request r. If the supplied authentication
3666 // does not match the username and password expected, a non-nil error is
3669 // This check is time-constant.
3671 // The first bool return value signifies auth success (true if successful) and
3672 // the second bool return value specifies whether the user can change the state
3673 // of the server (true) or whether the user is limited (false). The second is
3674 // always false if the first is.
3675 func (s *rpcServer) checkAuth(r *http.Request, require bool) (bool, bool, error) {
3676 authhdr := r.Header["Authorization"]
3677 if len(authhdr) <= 0 {
3679 rpcsLog.Warnf("RPC authentication failure from %s",
3681 return false, false, errors.New("auth failure")
3684 return false, false, nil
3687 authsha := sha256.Sum256([]byte(authhdr[0]))
3689 // Check for limited auth first as in environments with limited users, those
3690 // are probably expected to have a higher volume of calls
3691 limitcmp := subtle.ConstantTimeCompare(authsha[:], s.limitauthsha[:])
3693 return true, false, nil
3696 // Check for admin-level auth
3697 cmp := subtle.ConstantTimeCompare(authsha[:], s.authsha[:])
3699 return true, true, nil
3702 // Request's auth doesn't match either user
3703 rpcsLog.Warnf("RPC authentication failure from %s", r.RemoteAddr)
3704 return false, false, errors.New("auth failure")
3707 // parsedRPCCmd represents a JSON-RPC request object that has been parsed into
3708 // a known concrete command along with any error that might have happened while
3710 type parsedRPCCmd struct {
3714 err *btcjson.RPCError
3717 // standardCmdResult checks that a parsed command is a standard Bitcoin JSON-RPC
3718 // command and runs the appropriate handler to reply to the command. Any
3719 // commands which are not recognized or not implemented will return an error
3720 // suitable for use in replies.
3721 func (s *rpcServer) standardCmdResult(cmd *parsedRPCCmd, closeChan <-chan struct{}) (interface{}, error) {
3722 handler, ok := rpcHandlers[cmd.method]
3726 _, ok = rpcAskWallet[cmd.method]
3728 handler = handleAskWallet
3731 _, ok = rpcUnimplemented[cmd.method]
3733 handler = handleUnimplemented
3736 return nil, btcjson.ErrRPCMethodNotFound
3739 return handler(s, cmd.cmd, closeChan)
3742 // parseCmd parses a JSON-RPC request object into known concrete command. The
3743 // err field of the returned parsedRPCCmd struct will contain an RPC error that
3744 // is suitable for use in replies if the command is invalid in some way such as
3745 // an unregistered command or invalid parameters.
3746 func parseCmd(request *btcjson.Request) *parsedRPCCmd {
3747 var parsedCmd parsedRPCCmd
3748 parsedCmd.id = request.ID
3749 parsedCmd.method = request.Method
3751 cmd, err := btcjson.UnmarshalCmd(request)
3753 // When the error is because the method is not registered,
3754 // produce a method not found RPC error.
3755 if jerr, ok := err.(btcjson.Error); ok &&
3756 jerr.ErrorCode == btcjson.ErrUnregisteredMethod {
3758 parsedCmd.err = btcjson.ErrRPCMethodNotFound
3762 // Otherwise, some type of invalid parameters is the
3763 // cause, so produce the equivalent RPC error.
3764 parsedCmd.err = btcjson.NewRPCError(
3765 btcjson.ErrRPCInvalidParams.Code, err.Error())
3773 // createMarshalledReply returns a new marshalled JSON-RPC response given the
3774 // passed parameters. It will automatically convert errors that are not of
3775 // the type *btcjson.RPCError to the appropriate type as needed.
3776 func createMarshalledReply(id, result interface{}, replyErr error) ([]byte, error) {
3777 var jsonErr *btcjson.RPCError
3778 if replyErr != nil {
3779 if jErr, ok := replyErr.(*btcjson.RPCError); ok {
3782 jsonErr = internalRPCError(replyErr.Error(), "")
3786 return btcjson.MarshalResponse(id, result, jsonErr)
3789 // jsonRPCRead handles reading and responding to RPC messages.
3790 func (s *rpcServer) jsonRPCRead(w http.ResponseWriter, r *http.Request, isAdmin bool) {
3791 if atomic.LoadInt32(&s.shutdown) != 0 {
3795 // Read and close the JSON-RPC request body from the caller.
3796 body, err := ioutil.ReadAll(r.Body)
3799 errCode := http.StatusBadRequest
3800 http.Error(w, fmt.Sprintf("%d error reading JSON message: %v",
3801 errCode, err), errCode)
3805 // Unfortunately, the http server doesn't provide the ability to
3806 // change the read deadline for the new connection and having one breaks
3807 // long polling. However, not having a read deadline on the initial
3808 // connection would mean clients can connect and idle forever. Thus,
3809 // hijack the connecton from the HTTP server, clear the read deadline,
3810 // and handle writing the response manually.
3811 hj, ok := w.(http.Hijacker)
3813 errMsg := "webserver doesn't support hijacking"
3814 rpcsLog.Warnf(errMsg)
3815 errCode := http.StatusInternalServerError
3816 http.Error(w, strconv.Itoa(errCode)+" "+errMsg, errCode)
3819 conn, buf, err := hj.Hijack()
3821 rpcsLog.Warnf("Failed to hijack HTTP connection: %v", err)
3822 errCode := http.StatusInternalServerError
3823 http.Error(w, strconv.Itoa(errCode)+" "+err.Error(), errCode)
3828 conn.SetReadDeadline(timeZeroVal)
3830 // Attempt to parse the raw body into a JSON-RPC request.
3831 var responseID interface{}
3833 var result interface{}
3834 var request btcjson.Request
3835 if err := json.Unmarshal(body, &request); err != nil {
3836 jsonErr = &btcjson.RPCError{
3837 Code: btcjson.ErrRPCParse.Code,
3838 Message: "Failed to parse request: " + err.Error(),
3842 // The JSON-RPC 1.0 spec defines that notifications must have their "id"
3843 // set to null and states that notifications do not have a response.
3845 // A JSON-RPC 2.0 notification is a request with "json-rpc":"2.0", and
3846 // without an "id" member. The specification states that notifications
3847 // must not be responded to. JSON-RPC 2.0 permits the null value as a
3848 // valid request id, therefore such requests are not notifications.
3850 // Bitcoin Core serves requests with "id":null or even an absent "id",
3851 // and responds to such requests with "id":null in the response.
3853 // Btcd does not respond to any request without and "id" or "id":null,
3854 // regardless the indicated JSON-RPC protocol version unless RPC quirks
3855 // are enabled. With RPC quirks enabled, such requests will be responded
3856 // to if the reqeust does not indicate JSON-RPC version.
3858 // RPC quirks can be enabled by the user to avoid compatibility issues
3859 // with software relying on Core's behavior.
3860 if request.ID == nil && !(cfg.RPCQuirks && request.Jsonrpc == "") {
3864 // The parse was at least successful enough to have an ID so
3865 // set it for the response.
3866 responseID = request.ID
3868 // Setup a close notifier. Since the connection is hijacked,
3869 // the CloseNotifer on the ResponseWriter is not available.
3870 closeChan := make(chan struct{}, 1)
3872 _, err := conn.Read(make([]byte, 1))
3878 // Check if the user is limited and set error if method unauthorized
3880 if _, ok := rpcLimited[request.Method]; !ok {
3881 jsonErr = &btcjson.RPCError{
3882 Code: btcjson.ErrRPCInvalidParams.Code,
3883 Message: "limited user not authorized for this method",
3889 // Attempt to parse the JSON-RPC request into a known concrete
3891 parsedCmd := parseCmd(&request)
3892 if parsedCmd.err != nil {
3893 jsonErr = parsedCmd.err
3895 result, jsonErr = s.standardCmdResult(parsedCmd, closeChan)
3900 // Marshal the response.
3901 msg, err := createMarshalledReply(responseID, result, jsonErr)
3903 rpcsLog.Errorf("Failed to marshal reply: %v", err)
3907 // Write the response.
3908 err = s.writeHTTPResponseHeaders(r, w.Header(), http.StatusOK, buf)
3913 if _, err := buf.Write(msg); err != nil {
3914 rpcsLog.Errorf("Failed to write marshalled reply: %v", err)
3917 // Terminate with newline to maintain compatibility with Bitcoin Core.
3918 if err := buf.WriteByte('\n'); err != nil {
3919 rpcsLog.Errorf("Failed to append terminating newline to reply: %v", err)
3923 // jsonAuthFail sends a message back to the client if the http auth is rejected.
3924 func jsonAuthFail(w http.ResponseWriter) {
3925 w.Header().Add("WWW-Authenticate", `Basic realm="btcd RPC"`)
3926 http.Error(w, "401 Unauthorized.", http.StatusUnauthorized)
3929 // Start is used by server.go to start the rpc listener.
3930 func (s *rpcServer) Start() {
3931 if atomic.AddInt32(&s.started, 1) != 1 {
3935 rpcsLog.Trace("Starting RPC server")
3936 rpcServeMux := http.NewServeMux()
3937 httpServer := &http.Server{
3938 Handler: rpcServeMux,
3940 // Timeout connections which don't complete the initial
3941 // handshake within the allowed timeframe.
3942 ReadTimeout: time.Second * rpcAuthTimeoutSeconds,
3944 rpcServeMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
3945 w.Header().Set("Connection", "close")
3946 w.Header().Set("Content-Type", "application/json")
3949 // Limit the number of connections to max allowed.
3950 if s.limitConnections(w, r.RemoteAddr) {
3954 // Keep track of the number of connected clients.
3955 s.incrementClients()
3956 defer s.decrementClients()
3957 _, isAdmin, err := s.checkAuth(r, true)
3963 // Read and respond to the request.
3964 s.jsonRPCRead(w, r, isAdmin)
3967 // Websocket endpoint.
3968 rpcServeMux.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
3969 authenticated, isAdmin, err := s.checkAuth(r, false)
3975 // Attempt to upgrade the connection to a websocket connection
3976 // using the default size for read/write buffers.
3977 ws, err := websocket.Upgrade(w, r, nil, 0, 0)
3979 if _, ok := err.(websocket.HandshakeError); !ok {
3980 rpcsLog.Errorf("Unexpected websocket error: %v",
3983 http.Error(w, "400 Bad Request.", http.StatusBadRequest)
3986 s.WebsocketHandler(ws, r.RemoteAddr, authenticated, isAdmin)
3989 for _, listener := range s.cfg.Listeners {
3991 go func(listener net.Listener) {
3992 rpcsLog.Infof("RPC server listening on %s", listener.Addr())
3993 httpServer.Serve(listener)
3994 rpcsLog.Tracef("RPC listener done for %s", listener.Addr())
4002 // genCertPair generates a key/cert pair to the paths provided.
4003 func genCertPair(certFile, keyFile string) error {
4004 rpcsLog.Infof("Generating TLS certificates...")
4006 org := "btcd autogenerated cert"
4007 validUntil := time.Now().Add(10 * 365 * 24 * time.Hour)
4008 cert, key, err := btcutil.NewTLSCertPair(org, validUntil, nil)
4013 // Write cert and key files.
4014 if err = ioutil.WriteFile(certFile, cert, 0666); err != nil {
4017 if err = ioutil.WriteFile(keyFile, key, 0600); err != nil {
4022 rpcsLog.Infof("Done generating TLS certificates")
4026 // rpcserverPeer represents a peer for use with the RPC server.
4028 // The interface contract requires that all of these methods are safe for
4029 // concurrent access.
4030 type rpcserverPeer interface {
4031 // ToPeer returns the underlying peer instance.
4034 // IsTxRelayDisabled returns whether or not the peer has disabled
4035 // transaction relay.
4036 IsTxRelayDisabled() bool
4038 // BanScore returns the current integer value that represents how close
4039 // the peer is to being banned.
4042 // FeeFilter returns the requested current minimum fee rate for which
4043 // transactions should be announced.
4047 // rpcserverConnManager represents a connection manager for use with the RPC
4050 // The interface contract requires that all of these methods are safe for
4051 // concurrent access.
4052 type rpcserverConnManager interface {
4053 // Connect adds the provided address as a new outbound peer. The
4054 // permanent flag indicates whether or not to make the peer persistent
4055 // and reconnect if the connection is lost. Attempting to connect to an
4056 // already existing peer will return an error.
4057 Connect(addr string, permanent bool) error
4059 // RemoveByID removes the peer associated with the provided id from the
4060 // list of persistent peers. Attempting to remove an id that does not
4061 // exist will return an error.
4062 RemoveByID(id int32) error
4064 // RemoveByAddr removes the peer associated with the provided address
4065 // from the list of persistent peers. Attempting to remove an address
4066 // that does not exist will return an error.
4067 RemoveByAddr(addr string) error
4069 // DisconnectByID disconnects the peer associated with the provided id.
4070 // This applies to both inbound and outbound peers. Attempting to
4071 // remove an id that does not exist will return an error.
4072 DisconnectByID(id int32) error
4074 // DisconnectByAddr disconnects the peer associated with the provided
4075 // address. This applies to both inbound and outbound peers.
4076 // Attempting to remove an address that does not exist will return an
4078 DisconnectByAddr(addr string) error
4080 // ConnectedCount returns the number of currently connected peers.
4081 ConnectedCount() int32
4083 // NetTotals returns the sum of all bytes received and sent across the
4084 // network for all peers.
4085 NetTotals() (uint64, uint64)
4087 // ConnectedPeers returns an array consisting of all connected peers.
4088 ConnectedPeers() []rpcserverPeer
4090 // PersistentPeers returns an array consisting of all the persistent
4092 PersistentPeers() []rpcserverPeer
4094 // BroadcastMessage sends the provided message to all currently
4096 BroadcastMessage(msg wire.Message)
4098 // AddRebroadcastInventory adds the provided inventory to the list of
4099 // inventories to be rebroadcast at random intervals until they show up
4101 AddRebroadcastInventory(iv *wire.InvVect, data interface{})
4103 // RelayTransactions generates and relays inventory vectors for all of
4104 // the passed transactions to all connected peers.
4105 RelayTransactions(txns []*mempool.TxDesc)
4108 // rpcserverSyncManager represents a sync manager for use with the RPC server.
4110 // The interface contract requires that all of these methods are safe for
4111 // concurrent access.
4112 type rpcserverSyncManager interface {
4113 // IsCurrent returns whether or not the sync manager believes the chain
4114 // is current as compared to the rest of the network.
4117 // SubmitBlock submits the provided block to the network after
4118 // processing it locally.
4119 SubmitBlock(block *btcutil.Block, flags blockchain.BehaviorFlags) (bool, error)
4121 // Pause pauses the sync manager until the returned channel is closed.
4122 Pause() chan<- struct{}
4124 // SyncPeerID returns the ID of the peer that is currently the peer being
4125 // used to sync from or 0 if there is none.
4128 // LocateHeaders returns the headers of the blocks after the first known
4129 // block in the provided locators until the provided stop hash or the
4130 // current tip is reached, up to a max of wire.MaxBlockHeadersPerMsg
4132 LocateHeaders(locators []*chainhash.Hash, hashStop *chainhash.Hash) []wire.BlockHeader
4135 // rpcserverConfig is a descriptor containing the RPC server configuration.
4136 type rpcserverConfig struct {
4137 // Listeners defines a slice of listeners for which the RPC server will
4138 // take ownership of and accept connections. Since the RPC server takes
4139 // ownership of these listeners, they will be closed when the RPC server
4141 Listeners []net.Listener
4143 // StartupTime is the unix timestamp for when the server that is hosting
4144 // the RPC server started.
4147 // ConnMgr defines the connection manager for the RPC server to use. It
4148 // provides the RPC server with a means to do things such as add,
4149 // remove, connect, disconnect, and query peers as well as other
4150 // connection-related data and tasks.
4151 ConnMgr rpcserverConnManager
4153 // SyncMgr defines the sync manager for the RPC server to use.
4154 SyncMgr rpcserverSyncManager
4156 // These fields allow the RPC server to interface with the local block
4157 // chain data and state.
4158 TimeSource blockchain.MedianTimeSource
4159 Chain *blockchain.BlockChain
4160 ChainParams *chaincfg.Params
4163 // TxMemPool defines the transaction memory pool to interact with.
4164 TxMemPool *mempool.TxPool
4166 // These fields allow the RPC server to interface with mining.
4168 // Generator produces block templates and the CPUMiner solves them using
4169 // the CPU. CPU mining is typically only useful for test purposes when
4170 // doing regression or simulation testing.
4171 Generator *mining.BlkTmplGenerator
4172 CPUMiner *cpuminer.CPUMiner
4174 // These fields define any optional indexes the RPC server can make use
4175 // of to provide additional data when queried.
4176 TxIndex *indexers.TxIndex
4177 AddrIndex *indexers.AddrIndex
4180 // newRPCServer returns a new instance of the rpcServer struct.
4181 func newRPCServer(config *rpcserverConfig) (*rpcServer, error) {
4184 statusLines: make(map[int]string),
4185 gbtWorkState: newGbtWorkState(config.TimeSource),
4186 helpCacher: newHelpCacher(),
4187 requestProcessShutdown: make(chan struct{}),
4188 quit: make(chan int),
4190 if cfg.RPCUser != "" && cfg.RPCPass != "" {
4191 login := cfg.RPCUser + ":" + cfg.RPCPass
4192 auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login))
4193 rpc.authsha = sha256.Sum256([]byte(auth))
4195 if cfg.RPCLimitUser != "" && cfg.RPCLimitPass != "" {
4196 login := cfg.RPCLimitUser + ":" + cfg.RPCLimitPass
4197 auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login))
4198 rpc.limitauthsha = sha256.Sum256([]byte(auth))
4200 rpc.ntfnMgr = newWsNotificationManager(&rpc)
4201 rpc.cfg.Chain.Subscribe(rpc.handleBlockchainNotification)
4206 // Callback for notifications from blockchain. It notifies clients that are
4207 // long polling for changes or subscribed to websockets notifications.
4208 func (s *rpcServer) handleBlockchainNotification(notification *blockchain.Notification) {
4209 switch notification.Type {
4210 case blockchain.NTBlockAccepted:
4211 block, ok := notification.Data.(*btcutil.Block)
4213 rpcsLog.Warnf("Chain accepted notification is not a block.")
4217 // Allow any clients performing long polling via the
4218 // getblocktemplate RPC to be notified when the new block causes
4219 // their old block template to become stale.
4220 s.gbtWorkState.NotifyBlockConnected(block.Hash())
4222 case blockchain.NTBlockConnected:
4223 block, ok := notification.Data.(*btcutil.Block)
4225 rpcsLog.Warnf("Chain connected notification is not a block.")
4229 // Notify registered websocket clients of incoming block.
4230 s.ntfnMgr.NotifyBlockConnected(block)
4232 case blockchain.NTBlockDisconnected:
4233 block, ok := notification.Data.(*btcutil.Block)
4235 rpcsLog.Warnf("Chain disconnected notification is not a block.")
4239 // Notify registered websocket clients.
4240 s.ntfnMgr.NotifyBlockDisconnected(block)
4245 rpcHandlers = rpcHandlersBeforeInit
4246 rand.Seed(time.Now().UnixNano())