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