diff --git a/btcec/signature.go b/btcec/signature.go index ae94e81bc..9b2765207 100644 --- a/btcec/signature.go +++ b/btcec/signature.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2014 The btcsuite developers +// Copyright (c) 2013-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -9,12 +9,11 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/hmac" + "crypto/sha256" "errors" "fmt" "hash" "math/big" - - "github.com/btcsuite/fastsha256" ) // Errors returned by canonicalPadding. @@ -455,7 +454,7 @@ func nonceRFC6979(privkey *big.Int, hash []byte) *big.Int { curve := S256() q := curve.Params().N x := privkey - alg := fastsha256.New + alg := sha256.New qlen := q.BitLen() holen := alg().Size() diff --git a/btcec/signature_test.go b/btcec/signature_test.go index 37c7267ed..2ec05d3be 100644 --- a/btcec/signature_test.go +++ b/btcec/signature_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2016 The btcsuite developers +// Copyright (c) 2013-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -7,12 +7,11 @@ package btcec import ( "bytes" "crypto/rand" + "crypto/sha256" "encoding/hex" "fmt" "math/big" "testing" - - "github.com/btcsuite/fastsha256" ) type signatureTest struct { @@ -558,7 +557,7 @@ func TestRFC6979(t *testing.T) { for i, test := range tests { privKey, _ := PrivKeyFromBytes(S256(), decodeHex(test.key)) - hash := fastsha256.Sum256([]byte(test.msg)) + hash := sha256.Sum256([]byte(test.msg)) // Ensure deterministically generated nonce is the expected value. gotNonce := nonceRFC6979(privKey.D, hash[:]).Bytes() diff --git a/chaincfg/chainhash/hashfuncs.go b/chaincfg/chainhash/hashfuncs.go index ae7a380ae..bf74f73c3 100644 --- a/chaincfg/chainhash/hashfuncs.go +++ b/chaincfg/chainhash/hashfuncs.go @@ -1,33 +1,33 @@ // Copyright (c) 2015 The Decred developers -// Copyright (c) 2016 The btcsuite developers +// Copyright (c) 2016-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. package chainhash -import "github.com/btcsuite/fastsha256" +import "crypto/sha256" // HashB calculates hash(b) and returns the resulting bytes. func HashB(b []byte) []byte { - hash := fastsha256.Sum256(b) + hash := sha256.Sum256(b) return hash[:] } // HashH calculates hash(b) and returns the resulting bytes as a Hash. func HashH(b []byte) Hash { - return Hash(fastsha256.Sum256(b)) + return Hash(sha256.Sum256(b)) } // DoubleHashB calculates hash(hash(b)) and returns the resulting bytes. func DoubleHashB(b []byte) []byte { - first := fastsha256.Sum256(b) - second := fastsha256.Sum256(first[:]) + first := sha256.Sum256(b) + second := sha256.Sum256(first[:]) return second[:] } // DoubleHashH calculates hash(hash(b)) and returns the resulting bytes as a // Hash. func DoubleHashH(b []byte) Hash { - first := fastsha256.Sum256(b) - return Hash(fastsha256.Sum256(first[:])) + first := sha256.Sum256(b) + return Hash(sha256.Sum256(first[:])) } diff --git a/config.go b/config.go index c767ea67e..e65794a1a 100644 --- a/config.go +++ b/config.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2016 The btcsuite developers +// Copyright (c) 2013-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -137,7 +137,6 @@ type config struct { BlockMinSize uint32 `long:"blockminsize" description:"Mininum block size in bytes to be used when creating a block"` BlockMaxSize uint32 `long:"blockmaxsize" description:"Maximum block size in bytes to be used when creating a block"` BlockPrioritySize uint32 `long:"blockprioritysize" description:"Size in bytes for high-priority/low-fee transactions when creating a block"` - GetWorkKeys []string `long:"getworkkey" description:"DEPRECATED -- Use the --miningaddr option instead"` NoPeerBloomFilters bool `long:"nopeerbloomfilters" description:"Disable bloom filtering support"` SigCacheMaxSize uint `long:"sigcachemaxsize" description:"The maximum number of entries in the signature verification cache"` BlocksOnly bool `long:"blocksonly" description:"Do not accept transactions from remote peers."` @@ -717,30 +716,8 @@ func loadConfig() (*config, []string, error) { return nil, nil, err } - // Check getwork keys are valid and saved parsed versions. - cfg.miningAddrs = make([]btcutil.Address, 0, len(cfg.GetWorkKeys)+ - len(cfg.MiningAddrs)) - for _, strAddr := range cfg.GetWorkKeys { - addr, err := btcutil.DecodeAddress(strAddr, - activeNetParams.Params) - if err != nil { - str := "%s: getworkkey '%s' failed to decode: %v" - err := fmt.Errorf(str, funcName, strAddr, err) - fmt.Fprintln(os.Stderr, err) - fmt.Fprintln(os.Stderr, usageMessage) - return nil, nil, err - } - if !addr.IsForNet(activeNetParams.Params) { - str := "%s: getworkkey '%s' is on the wrong network" - err := fmt.Errorf(str, funcName, strAddr) - fmt.Fprintln(os.Stderr, err) - fmt.Fprintln(os.Stderr, usageMessage) - return nil, nil, err - } - cfg.miningAddrs = append(cfg.miningAddrs, addr) - } - // Check mining addresses are valid and saved parsed versions. + cfg.miningAddrs = make([]btcutil.Address, 0, len(cfg.MiningAddrs)) for _, strAddr := range cfg.MiningAddrs { addr, err := btcutil.DecodeAddress(strAddr, activeNetParams.Params) if err != nil { diff --git a/doc.go b/doc.go index 42c76e201..07fff9e48 100644 --- a/doc.go +++ b/doc.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2016 The btcsuite developers +// Copyright (c) 2013-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -106,7 +106,6 @@ Application Options: a block (750000) --blockprioritysize= Size in bytes for high-priority/low-fee transactions when creating a block (50000) - --getworkkey= DEPRECATED -- Use the --miningaddr option instead --nopeerbloomfilters Disable bloom filtering support. --sigcachemaxsize= The maximum number of entries in the signature verification cache. diff --git a/docs/README.md b/docs/README.md index 1d90b4fa3..838b286bb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -155,9 +155,8 @@ For a list of available options, run: `$ btcctl --help` **2.4 Mining**
-btcd supports both the `getwork` and `getblocktemplate` RPCs although the -`getwork` RPC is deprecated and will likely be removed in a future release. -The limited user cannot access these RPCs.
+btcd supports the `getblocktemplate` RPC. +The limited user cannot access this RPC.
**1. Add the payment addresses with the `miningaddr` option.**
diff --git a/docs/json_rpc_api.md b/docs/json_rpc_api.md index 2e2cbd5d0..20e4bdffe 100644 --- a/docs/json_rpc_api.md +++ b/docs/json_rpc_api.md @@ -170,15 +170,14 @@ the method name for further details such as parameter and return information. |20|[getpeerinfo](#getpeerinfo)|N|Returns information about each connected network peer as an array of json objects.| |21|[getrawmempool](#getrawmempool)|Y|Returns an array of hashes for all of the transactions currently in the memory pool.| |22|[getrawtransaction](#getrawtransaction)|Y|Returns information about a transaction given its hash.| -|23|[getwork](#getwork)|N|Returns formatted hash data to work on or checks and submits solved data.
NOTE: Since btcd does not have the wallet integrated to provide payment addresses, btcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function.| -|24|[help](#help)|Y|Returns a list of all commands or help for a specified command.| -|25|[ping](#ping)|N|Queues a ping to be sent to each connected peer.| -|26|[sendrawtransaction](#sendrawtransaction)|Y|Submits the serialized, hex-encoded transaction to the local peer and relays it to the network.
btcd does not yet implement the `allowhighfees` parameter, so it has no effect| -|27|[setgenerate](#setgenerate) |N|Set the server to generate coins (mine) or not.
NOTE: Since btcd does not have the wallet integrated to provide payment addresses, btcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function.| -|28|[stop](#stop)|N|Shutdown btcd.| -|29|[submitblock](#submitblock)|Y|Attempts to submit a new serialized, hex-encoded block to the network.| -|30|[validateaddress](#validateaddress)|Y|Verifies the given address is valid. NOTE: Since btcd does not have a wallet integrated, btcd will only return whether the address is valid or not.| -|31|[verifychain](#verifychain)|N|Verifies the block chain database.| +|23|[help](#help)|Y|Returns a list of all commands or help for a specified command.| +|24|[ping](#ping)|N|Queues a ping to be sent to each connected peer.| +|25|[sendrawtransaction](#sendrawtransaction)|Y|Submits the serialized, hex-encoded transaction to the local peer and relays it to the network.
btcd does not yet implement the `allowhighfees` parameter, so it has no effect| +|26|[setgenerate](#setgenerate) |N|Set the server to generate coins (mine) or not.
NOTE: Since btcd does not have the wallet integrated to provide payment addresses, btcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function.| +|27|[stop](#stop)|N|Shutdown btcd.| +|28|[submitblock](#submitblock)|Y|Attempts to submit a new serialized, hex-encoded block to the network.| +|29|[validateaddress](#validateaddress)|Y|Verifies the given address is valid. NOTE: Since btcd does not have a wallet integrated, btcd will only return whether the address is valid or not.| +|30|[verifychain](#verifychain)|N|Verifies the block chain database.|
**5.2 Method Details**
@@ -442,21 +441,6 @@ Example Return|`{`
  `"bytes": 310768,`
  `"size": |Example Return (verbose=1)|`{`
  `"hex": "01000000010000000000000000000000000000000000000000000000000000000000000000f...",`
  `"txid": "90743aad855880e517270550d2a881627d84db5265142fd1e7fb7add38b08be9",`
  `"version": 1,`
  `"locktime": 0,`
  `"vin": [`
  For coinbase transactions:
    `{ (json object)`
      `"coinbase": "03708203062f503253482f04066d605108f800080100000ea2122f6f7a636f696e4065757374726174756d2f",`
      `"sequence": 0,`
    `}`
  For non-coinbase transactions:
    `{`
      `"txid": "60ac4b057247b3d0b9a8173de56b5e1be8c1d1da970511c626ef53706c66be04",`
      `"vout": 0,`
      `"scriptSig": {`
        `"asm": "3046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8f0...",`
        `"hex": "493046022100cb42f8df44eca83dd0a727988dcde9384953e830b1f8004d57485e2ede1b9c8...",`
      `}`
      `"sequence": 4294967295,`
    `}`
  `]`
  `"vout": [`
    `{`
      `"value": 25.1394,`
      `"n": 0,`
      `"scriptPubKey": {`
        `"asm": "OP_DUP OP_HASH160 ea132286328cfc819457b9dec386c4b5c84faa5c OP_EQUALVERIFY OP_CHECKSIG",`
        `"hex": "76a914ea132286328cfc819457b9dec386c4b5c84faa5c88ac",`
        `"reqSigs": 1,`
        `"type": "pubkeyhash"`
        `"addresses": [`
          `"1NLg3QJMsMQGM5KEUaEu5ADDmKQSLHwmyh",`
        `]`
      `}`
    `}`
  `]`
`}`| [Return to Overview](#MethodOverview)
-*** -
- -| | | -|---|---| -|Method|getwork| -|Parameters|1. data (string, optional) - The hex| -|Description|Returns information about a transaction given its hash.| -|Notes|NOTE: Since btcd does not have the wallet integrated to provide payment addresses, btcd must be configured via the `--miningaddr` option to provide which payment addresses to pay created blocks to for this RPC to function. -|Returns (data not specified)|`{ (json object)`
  `"data": "hex", (string) hex-encoded block data`
  `"hash1": "hex", (string) (DEPRECATED) hex-encoded formatted hash buffer`
  `"midstate": "hex", (string) (DEPRECATED) hex-encoded precomputed hash state after hashing first half of the data`
  `"target": "hex", (string) the hex-encoded little-endian hash target`
`}`| -|Returns (data specified)|`true` or `false` (boolean)| -|Example Return (data not specified)|`{`
  `"data": "00000002c39b5d2b7a1e8f7356a1efce26b24bd15d7d906e85341ef9cec99b6a000000006474f...",`
  `"hash1": "00000000000000000000000000000000000000000000000000000000000000000000008000000...",`
  `"midstate": "ae4a80fc51476e452de855b4e20d5f33418c50fc7cae3b1ecd5badb819b8a584",`
  `"target": "0000000000000000000000000000000000000000000000008c96010000000000",`
`}`| -|Example Return (data specified)|`true`| -[Return to Overview](#MethodOverview)
- ***
diff --git a/glide.lock b/glide.lock index 133838f87..259aa2cc5 100644 --- a/glide.lock +++ b/glide.lock @@ -1,21 +1,19 @@ -hash: ebeea81fdd8ab49cce0e295ae834f8fbb0fb6e1b8e618a5059aceff477ef6596 -updated: 2016-12-09T12:53:49.172263045-05:00 +hash: 3483e97fe9cd4e2c998f05ca648ce21767e1a4b955919aeffbc6bfe87d9b0648 +updated: 2017-01-11T09:52:36.894361964-05:00 imports: - name: github.com/btcsuite/btclog version: 73889fb79bd687870312b6e40effcecffbd57d30 - name: github.com/btcsuite/btcrpcclient - version: 7903290fd9956021ed7b65463f8667df345b365e + version: 5ce0ed600997eafaed25ad4936c1d84ec6ad2b5a - name: github.com/btcsuite/btcutil - version: 96e858f48ed95f9245e765d98be0ee01176409c7 + version: bca6409ade96981b0e77a2a7d358be53b340a1a7 subpackages: - . - base58 - bloom - hdkeychain -- name: github.com/btcsuite/fastsha256 - version: 637e656429416087660c84436a2a035d69d54e2e - name: github.com/btcsuite/go-socks - version: cfe8b59e565c1a5bd4e2005d77cd9aa8b2e14524 + version: 4720035b7bfd2a9bb130b1c184f8bbe41b6f0d0f subpackages: - socks - name: github.com/btcsuite/golangcrypto diff --git a/glide.yaml b/glide.yaml index adceeb8f4..c6af102ff 100644 --- a/glide.yaml +++ b/glide.yaml @@ -8,7 +8,6 @@ import: - base58 - hdkeychain - package: github.com/btcsuite/btcrpcclient -- package: github.com/btcsuite/fastsha256 - package: github.com/btcsuite/go-socks subpackages: - socks diff --git a/rpcserver.go b/rpcserver.go index 5581699a2..3f9868b53 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -7,10 +7,10 @@ package main import ( "bytes" + "crypto/sha256" "crypto/subtle" "crypto/tls" "encoding/base64" - "encoding/binary" "encoding/hex" "encoding/json" "errors" @@ -39,7 +39,6 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" - "github.com/btcsuite/fastsha256" "github.com/btcsuite/websocket" ) @@ -61,23 +60,6 @@ const ( // 256-bit integer. uint256Size = 32 - // getworkDataLen is the length of the data field of the getwork RPC. - // It consists of the serialized block header plus the internal sha256 - // padding. The internal sha256 padding consists of a single 1 bit - // followed by enough zeros to pad the message out to 56 bytes followed - // by length of the message in bits encoded as a big-endian uint64 - // (8 bytes). Thus, the resulting length is a multiple of the sha256 - // block size (64 bytes). - getworkDataLen = (1 + ((wire.MaxBlockHeaderPayload + 8) / - fastsha256.BlockSize)) * fastsha256.BlockSize - - // hash1Len is the length of the hash1 field of the getwork RPC. It - // consists of a zero hash plus the internal sha256 padding. See - // the getworkDataLen comment for details about the internal sha256 - // padding format. - hash1Len = (1 + ((chainhash.HashSize + 8) / fastsha256.BlockSize)) * - fastsha256.BlockSize - // gbtNonceRange is two 32-bit big-endian hexadecimal integers which // represent the valid ranges of nonces returned by the getblocktemplate // RPC. @@ -173,7 +155,6 @@ var rpcHandlersBeforeInit = map[string]commandHandler{ "getrawmempool": handleGetRawMempool, "getrawtransaction": handleGetRawTransaction, "gettxout": handleGetTxOut, - "getwork": handleGetWork, "help": handleHelp, "node": handleNode, "ping": handlePing, @@ -242,6 +223,7 @@ var rpcUnimplemented = map[string]struct{}{ "estimatepriority": {}, "getchaintips": {}, "getnetworkinfo": {}, + "getwork": {}, "invalidateblock": {}, "preciousblock": {}, "reconsiderblock": {}, @@ -329,33 +311,6 @@ func rpcNoTxInfoError(txHash *chainhash.Hash) *btcjson.RPCError { txHash)) } -// workStateBlockInfo houses information about how to reconstruct a block given -// its template and signature script. -type workStateBlockInfo struct { - msgBlock *wire.MsgBlock - signatureScript []byte -} - -// workState houses state that is used in between multiple RPC invocations to -// getwork. -type workState struct { - sync.Mutex - lastTxUpdate time.Time - lastGenerated time.Time - prevHash *chainhash.Hash - msgBlock *wire.MsgBlock - extraNonce uint64 - blockInfo map[chainhash.Hash]*workStateBlockInfo -} - -// newWorkState returns a new instance of a workState with all internal fields -// initialized and ready to use. -func newWorkState() *workState { - return &workState{ - blockInfo: make(map[chainhash.Hash]*workStateBlockInfo), - } -} - // gbtWorkState houses state that is used in between multiple RPC invocations to // getblocktemplate. type gbtWorkState struct { @@ -2590,41 +2545,6 @@ func handleGetRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan str return *rawTxn, nil } -// bigToLEUint256 returns the passed big integer as an unsigned 256-bit integer -// encoded as little-endian bytes. Numbers which are larger than the max -// unsigned 256-bit integer are truncated. -func bigToLEUint256(n *big.Int) [uint256Size]byte { - // Pad or truncate the big-endian big int to correct number of bytes. - nBytes := n.Bytes() - nlen := len(nBytes) - pad := 0 - start := 0 - if nlen <= uint256Size { - pad = uint256Size - nlen - } else { - start = nlen - uint256Size - } - var buf [uint256Size]byte - copy(buf[pad:], nBytes[start:]) - - // Reverse the bytes to little endian and return them. - for i := 0; i < uint256Size/2; i++ { - buf[i], buf[uint256Size-1-i] = buf[uint256Size-1-i], buf[i] - } - return buf -} - -// reverseUint32Array treats the passed bytes as a series of uint32s and -// reverses the byte order of each uint32. The passed byte slice must be a -// multiple of 4 for a correct result. The passed bytes slice is modified. -func reverseUint32Array(b []byte) { - blen := len(b) - for i := 0; i < blen; i += 4 { - b[i], b[i+3] = b[i+3], b[i] - b[i+1], b[i+2] = b[i+2], b[i+1] - } -} - // handleGetTxOut handles gettxout commands. func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { c := cmd.(*btcjson.GetTxOutCmd) @@ -2734,325 +2654,6 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i return txOutReply, nil } -// handleGetWorkRequest is a helper for handleGetWork which deals with -// generating and returning work to the caller. -// -// This function MUST be called with the RPC workstate locked. -func handleGetWorkRequest(s *rpcServer) (interface{}, error) { - state := s.workState - - // Generate a new block template when the current best block has - // changed or the transactions in the memory pool have been updated - // and it has been at least one minute since the last template was - // generated. - lastTxUpdate := s.server.txMemPool.LastUpdated() - best := s.server.blockManager.chain.BestSnapshot() - latestHash, latestHeight := best.Hash, best.Height - msgBlock := state.msgBlock - if msgBlock == nil || state.prevHash == nil || - !state.prevHash.IsEqual(latestHash) || - (state.lastTxUpdate != lastTxUpdate && - time.Now().After(state.lastGenerated.Add(time.Minute))) { - - // Reset the extra nonce and clear all cached template - // variations if the best block changed. - if state.prevHash != nil && !state.prevHash.IsEqual(latestHash) { - state.extraNonce = 0 - state.blockInfo = make(map[chainhash.Hash]*workStateBlockInfo) - } - - // Reset the previous best hash the block template was generated - // against so any errors below cause the next invocation to try - // again. - state.prevHash = nil - - // Choose a payment address at random. - payToAddr := cfg.miningAddrs[rand.Intn(len(cfg.miningAddrs))] - template, err := s.generator.NewBlockTemplate(payToAddr) - if err != nil { - context := "Failed to create new block template" - return nil, internalRPCError(err.Error(), context) - } - msgBlock = template.Block - - // Update work state to ensure another block template isn't - // generated until needed. - state.msgBlock = msgBlock - state.lastGenerated = time.Now() - state.lastTxUpdate = lastTxUpdate - state.prevHash = latestHash - - rpcsLog.Debugf("Generated block template (timestamp %v, extra "+ - "nonce %d, target %064x, merkle root %s, signature "+ - "script %x)", msgBlock.Header.Timestamp, - state.extraNonce, - blockchain.CompactToBig(msgBlock.Header.Bits), - msgBlock.Header.MerkleRoot, - msgBlock.Transactions[0].TxIn[0].SignatureScript) - } else { - // At this point, there is a saved block template and a new - // request for work was made, but either the available - // transactions haven't change or it hasn't been long enough to - // trigger a new block template to be generated. So, update the - // existing block template and track the variations so each - // variation can be regenerated if a caller finds an answer and - // makes a submission against it. - - // Update the time of the block template to the current time - // while accounting for the median time of the past several - // blocks per the chain consensus rules. - s.generator.UpdateBlockTime(msgBlock) - - // Increment the extra nonce and update the block template - // with the new value by regenerating the coinbase script and - // setting the merkle root to the new value. - state.extraNonce++ - err := s.generator.UpdateExtraNonce(msgBlock, latestHeight+1, - state.extraNonce) - if err != nil { - errStr := fmt.Sprintf("Failed to update extra nonce: "+ - "%v", err) - return nil, internalRPCError(errStr, "") - } - - rpcsLog.Debugf("Updated block template (timestamp %v, extra "+ - "nonce %d, target %064x, merkle root %s, signature "+ - "script %x)", msgBlock.Header.Timestamp, - state.extraNonce, - blockchain.CompactToBig(msgBlock.Header.Bits), - msgBlock.Header.MerkleRoot, - msgBlock.Transactions[0].TxIn[0].SignatureScript) - } - - // In order to efficiently store the variations of block templates that - // have been provided to callers, save a pointer to the block as well as - // the modified signature script keyed by the merkle root. This - // information, along with the data that is included in a work - // submission, is used to rebuild the block before checking the - // submitted solution. - coinbaseTx := msgBlock.Transactions[0] - state.blockInfo[msgBlock.Header.MerkleRoot] = &workStateBlockInfo{ - msgBlock: msgBlock, - signatureScript: coinbaseTx.TxIn[0].SignatureScript, - } - - // Serialize the block header into a buffer large enough to hold the - // the block header and the internal sha256 padding that is added and - // retuned as part of the data below. - data := make([]byte, 0, getworkDataLen) - buf := bytes.NewBuffer(data) - err := msgBlock.Header.Serialize(buf) - if err != nil { - errStr := fmt.Sprintf("Failed to serialize data: %v", err) - return nil, internalRPCError(errStr, "") - } - - // Calculate the midstate for the block header. The midstate here is - // the internal state of the sha256 algorithm for the first chunk of the - // block header (sha256 operates on 64-byte chunks) which is before the - // nonce. This allows sophisticated callers to avoid hashing the first - // chunk over and over while iterating the nonce range. - data = data[:buf.Len()] - midstate := fastsha256.MidState256(data) - - // Expand the data slice to include the full data buffer and apply the - // internal sha256 padding which consists of a single 1 bit followed - // by enough zeros to pad the message out to 56 bytes followed by the - // length of the message in bits encoded as a big-endian uint64 - // (8 bytes). Thus, the resulting length is a multiple of the sha256 - // block size (64 bytes). This makes the data ready for sophisticated - // caller to make use of only the second chunk along with the midstate - // for the first chunk. - data = data[:getworkDataLen] - data[wire.MaxBlockHeaderPayload] = 0x80 - binary.BigEndian.PutUint64(data[len(data)-8:], - wire.MaxBlockHeaderPayload*8) - - // Create the hash1 field which is a zero hash along with the internal - // sha256 padding as described above. This field is really quite - // useless, but it is required for compatibility with the reference - // implementation. - var hash1 [hash1Len]byte - hash1[chainhash.HashSize] = 0x80 - binary.BigEndian.PutUint64(hash1[len(hash1)-8:], chainhash.HashSize*8) - - // The final result reverses each of the fields to little endian. - // In particular, the data, hash1, and midstate fields are treated as - // arrays of uint32s (per the internal sha256 hashing state) which are - // in big endian, and thus each 4 bytes is byte swapped. The target is - // also in big endian, but it is treated as a uint256 and byte swapped - // to little endian accordingly. - // - // The fact the fields are reversed in this way is rather odd and likey - // an artifact of some legacy internal state in the reference - // implementation, but it is required for compatibility. - reverseUint32Array(data) - reverseUint32Array(hash1[:]) - reverseUint32Array(midstate[:]) - target := bigToLEUint256(blockchain.CompactToBig(msgBlock.Header.Bits)) - reply := &btcjson.GetWorkResult{ - Data: hex.EncodeToString(data), - Hash1: hex.EncodeToString(hash1[:]), - Midstate: hex.EncodeToString(midstate[:]), - Target: hex.EncodeToString(target[:]), - } - return reply, nil -} - -// handleGetWorkSubmission is a helper for handleGetWork which deals with -// the calling submitting work to be verified and processed. -// -// This function MUST be called with the RPC workstate locked. -func handleGetWorkSubmission(s *rpcServer, hexData string) (interface{}, error) { - // Ensure the provided data is sane. - if len(hexData)%2 != 0 { - hexData = "0" + hexData - } - data, err := hex.DecodeString(hexData) - if err != nil { - return false, rpcDecodeHexError(hexData) - } - if len(data) != getworkDataLen { - return false, &btcjson.RPCError{ - Code: btcjson.ErrRPCInvalidParameter, - Message: fmt.Sprintf("Argument must be "+ - "%d bytes (not %d)", getworkDataLen, - len(data)), - } - } - - // Reverse the data as if it were an array of 32-bit unsigned integers. - // The fact the getwork request and submission data is reversed in this - // way is rather odd and likey an artifact of some legacy internal state - // in the reference implementation, but it is required for - // compatibility. - reverseUint32Array(data) - - // Deserialize the block header from the data. - var submittedHeader wire.BlockHeader - bhBuf := bytes.NewReader(data[0:wire.MaxBlockHeaderPayload]) - err = submittedHeader.Deserialize(bhBuf) - if err != nil { - return false, &btcjson.RPCError{ - Code: btcjson.ErrRPCInvalidParameter, - Message: fmt.Sprintf("Argument does not "+ - "contain a valid block header: %v", err), - } - } - - // Look up the full block for the provided data based on the - // merkle root. Return false to indicate the solve failed if - // it's not available. - state := s.workState - blockInfo, ok := state.blockInfo[submittedHeader.MerkleRoot] - if !ok { - rpcsLog.Debugf("Block submitted via getwork has no matching "+ - "template for merkle root %s", - submittedHeader.MerkleRoot) - return false, nil - } - - // Reconstruct the block using the submitted header stored block info. - msgBlock := blockInfo.msgBlock - block := btcutil.NewBlock(msgBlock) - msgBlock.Header.Timestamp = submittedHeader.Timestamp - msgBlock.Header.Nonce = submittedHeader.Nonce - msgBlock.Transactions[0].TxIn[0].SignatureScript = blockInfo.signatureScript - merkles := blockchain.BuildMerkleTreeStore(block.Transactions()) - msgBlock.Header.MerkleRoot = *merkles[len(merkles)-1] - - // Ensure the submitted block hash is less than the target difficulty. - err = blockchain.CheckProofOfWork(block, activeNetParams.PowLimit) - if err != nil { - // Anything other than a rule violation is an unexpected error, - // so return that error as an internal error. - if _, ok := err.(blockchain.RuleError); !ok { - return false, internalRPCError("Unexpected error "+ - "while checking proof of work: "+err.Error(), - "") - } - - rpcsLog.Debugf("Block submitted via getwork does not meet "+ - "the required proof of work: %v", err) - return false, nil - } - - latestHash := s.server.blockManager.chain.BestSnapshot().Hash - if !msgBlock.Header.PrevBlock.IsEqual(latestHash) { - rpcsLog.Debugf("Block submitted via getwork with previous "+ - "block %s is stale", msgBlock.Header.PrevBlock) - return false, nil - } - - // Process this block using the same rules as blocks coming from other - // nodes. This will in turn relay it to the network like normal. - isOrphan, err := s.server.blockManager.ProcessBlock(block, blockchain.BFNone) - if err != nil || isOrphan { - // Anything other than a rule violation is an unexpected error, - // so return that error as an internal error. - if _, ok := err.(blockchain.RuleError); !ok { - return false, internalRPCError("Unexpected error "+ - "while processing block: "+err.Error(), "") - } - - rpcsLog.Infof("Block submitted via getwork rejected: %v", err) - return false, nil - } - - // The block was accepted. - rpcsLog.Infof("Block submitted via getwork accepted: %s", block.Hash()) - return true, nil -} - -// handleGetWork implements the getwork command. -func handleGetWork(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { - c := cmd.(*btcjson.GetWorkCmd) - - // Respond with an error if there are no addresses to pay the created - // blocks to. - if len(cfg.miningAddrs) == 0 { - return nil, &btcjson.RPCError{ - Code: btcjson.ErrRPCInternal.Code, - Message: "No payment addresses specified via --miningaddr", - } - } - - // Return an error if there are no peers connected since there is no - // way to relay a found block or receive transactions to work on. - // However, allow this state when running in the regression test or - // simulation test mode. - if !(cfg.RegressionTest || cfg.SimNet) && s.server.ConnectedCount() == 0 { - return nil, &btcjson.RPCError{ - Code: btcjson.ErrRPCClientNotConnected, - Message: "Bitcoin is not connected", - } - } - - // No point in generating or accepting work before the chain is synced. - currentHeight := s.server.blockManager.chain.BestSnapshot().Height - if currentHeight != 0 && !s.server.blockManager.IsCurrent() { - return nil, &btcjson.RPCError{ - Code: btcjson.ErrRPCClientInInitialDownload, - Message: "Bitcoin is downloading blocks...", - } - } - - // Protect concurrent access from multiple RPC invocations for work - // requests and submission. - s.workState.Lock() - defer s.workState.Unlock() - - // When the caller provides data, it is a submission of a supposedly - // solved block that needs to be checked and submitted to the network - // if valid. - if c.Data != nil && *c.Data != "" { - return handleGetWorkSubmission(s, *c.Data) - } - - // No data was provided, so the caller is requesting work. - return handleGetWorkRequest(s) -} - // handleHelp implements the help command. func handleHelp(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) { c := cmd.(*btcjson.HelpCmd) @@ -3885,15 +3486,14 @@ type rpcServer struct { generator *mining.BlkTmplGenerator server *server chain *blockchain.BlockChain - authsha [fastsha256.Size]byte - limitauthsha [fastsha256.Size]byte + authsha [sha256.Size]byte + limitauthsha [sha256.Size]byte ntfnMgr *wsNotificationManager numClients int32 statusLines map[int]string statusLock sync.RWMutex wg sync.WaitGroup listeners []net.Listener - workState *workState gbtWorkState *gbtWorkState helpCacher *helpCacher requestProcessShutdown chan struct{} @@ -4041,7 +3641,7 @@ func (s *rpcServer) checkAuth(r *http.Request, require bool) (bool, bool, error) return false, false, nil } - authsha := fastsha256.Sum256([]byte(authhdr[0])) + authsha := sha256.Sum256([]byte(authhdr[0])) // Check for limited auth first as in environments with limited users, those // are probably expected to have a higher volume of calls @@ -4387,7 +3987,6 @@ func newRPCServer(listenAddrs []string, generator *mining.BlkTmplGenerator, s *s generator: generator, chain: s.blockManager.chain, statusLines: make(map[int]string), - workState: newWorkState(), gbtWorkState: newGbtWorkState(s.timeSource), helpCacher: newHelpCacher(), requestProcessShutdown: make(chan struct{}), @@ -4396,12 +3995,12 @@ func newRPCServer(listenAddrs []string, generator *mining.BlkTmplGenerator, s *s if cfg.RPCUser != "" && cfg.RPCPass != "" { login := cfg.RPCUser + ":" + cfg.RPCPass auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login)) - rpc.authsha = fastsha256.Sum256([]byte(auth)) + rpc.authsha = sha256.Sum256([]byte(auth)) } if cfg.RPCLimitUser != "" && cfg.RPCLimitPass != "" { login := cfg.RPCLimitUser + ":" + cfg.RPCLimitPass auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login)) - rpc.limitauthsha = fastsha256.Sum256([]byte(auth)) + rpc.limitauthsha = sha256.Sum256([]byte(auth)) } rpc.ntfnMgr = newWsNotificationManager(&rpc) diff --git a/rpcserverhelp.go b/rpcserverhelp.go index 4c136f478..3e9e4151f 100644 --- a/rpcserverhelp.go +++ b/rpcserverhelp.go @@ -470,19 +470,6 @@ var helpDescsEnUS = map[string]string{ "gettxout-vout": "The index of the output", "gettxout-includemempool": "Include the mempool when true", - // GetWorkResult help. - "getworkresult-data": "Hex-encoded block data", - "getworkresult-hash1": "(DEPRECATED) Hex-encoded formatted hash buffer", - "getworkresult-midstate": "(DEPRECATED) Hex-encoded precomputed hash state after hashing first half of the data", - "getworkresult-target": "Hex-encoded little-endian hash target", - - // GetWorkCmd help. - "getwork--synopsis": "(DEPRECATED - Use getblocktemplate instead) Returns formatted hash data to work on or checks and submits solved data.", - "getwork-data": "Hex-encoded data to check", - "getwork--condition0": "no data provided", - "getwork--condition1": "data provided", - "getwork--result1": "Whether or not the solved data is valid and was added to the chain", - // HelpCmd help. "help--synopsis": "Returns a list of all commands or help for a specified command.", "help-command": "The command to retrieve help for", @@ -662,7 +649,6 @@ var rpcResultTypes = map[string][]interface{}{ "getrawmempool": {(*[]string)(nil), (*btcjson.GetRawMempoolVerboseResult)(nil)}, "getrawtransaction": {(*string)(nil), (*btcjson.TxRawResult)(nil)}, "gettxout": {(*btcjson.GetTxOutResult)(nil)}, - "getwork": {(*btcjson.GetWorkResult)(nil), (*bool)(nil)}, "node": nil, "help": {(*string)(nil), (*string)(nil)}, "ping": nil, diff --git a/rpcwebsocket.go b/rpcwebsocket.go index 94f6ae306..00d74653b 100644 --- a/rpcwebsocket.go +++ b/rpcwebsocket.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2016 The btcsuite developers +// Copyright (c) 2013-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -7,6 +7,7 @@ package main import ( "bytes" "container/list" + "crypto/sha256" "crypto/subtle" "encoding/base64" "encoding/hex" @@ -25,7 +26,6 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" - "github.com/btcsuite/fastsha256" "github.com/btcsuite/golangcrypto/ripemd160" "github.com/btcsuite/websocket" ) @@ -1010,7 +1010,7 @@ out: // Check credentials. login := authCmd.Username + ":" + authCmd.Passphrase auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login)) - authSha := fastsha256.Sum256([]byte(auth)) + authSha := sha256.Sum256([]byte(auth)) cmp := subtle.ConstantTimeCompare(authSha[:], c.server.authsha[:]) limitcmp := subtle.ConstantTimeCompare(authSha[:], c.server.limitauthsha[:]) if cmp != 1 && limitcmp != 1 { diff --git a/sample-btcd.conf b/sample-btcd.conf index 7d4996edd..71a5c928c 100644 --- a/sample-btcd.conf +++ b/sample-btcd.conf @@ -293,8 +293,8 @@ ; worth your while. ; generate=false -; Add addresses to pay mined blocks to for CPU mining and the block templates -; generated for the getwork RPC as desired. One address per line. +; Add addresses to pay mined blocks to for CPU mining and potentially in the +; block templates generated for the getblocktemplate RPC. One address per line. ; miningaddr=1yourbitcoinaddress ; miningaddr=1yourbitcoinaddress2 ; miningaddr=1yourbitcoinaddress3 diff --git a/txscript/opcode.go b/txscript/opcode.go index 0a81b45be..3e7a2495a 100644 --- a/txscript/opcode.go +++ b/txscript/opcode.go @@ -1,4 +1,4 @@ -// Copyright (c) 2013-2016 The btcsuite developers +// Copyright (c) 2013-2017 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -7,6 +7,7 @@ package txscript import ( "bytes" "crypto/sha1" + "crypto/sha256" "encoding/binary" "errors" "fmt" @@ -15,7 +16,6 @@ import ( "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" - "github.com/btcsuite/fastsha256" "github.com/btcsuite/golangcrypto/ripemd160" ) @@ -1890,7 +1890,7 @@ func opcodeSha256(op *parsedOpcode, vm *Engine) error { return err } - hash := fastsha256.Sum256(buf) + hash := sha256.Sum256(buf) vm.dstack.PushByteArray(hash[:]) return nil } @@ -1905,7 +1905,7 @@ func opcodeHash160(op *parsedOpcode, vm *Engine) error { return err } - hash := fastsha256.Sum256(buf) + hash := sha256.Sum256(buf) vm.dstack.PushByteArray(calcHash(hash[:], ripemd160.New())) return nil }