diff --git a/cpuminer.go b/cpuminer.go index 78fb8193..587288d3 100644 --- a/cpuminer.go +++ b/cpuminer.go @@ -318,8 +318,8 @@ out: // with false when conditions that trigger a stale block, so // a new block template can be generated. When the return is // true a solution was found, so submit the solved block. - if m.solveBlock(template.block, curHeight+1, ticker, quit) { - block := btcutil.NewBlock(template.block) + if m.solveBlock(template.Block, curHeight+1, ticker, quit) { + block := btcutil.NewBlock(template.Block) m.submitBlock(block) } } @@ -580,8 +580,8 @@ func (m *CPUMiner) GenerateNBlocks(n uint32) ([]*wire.ShaHash, error) { // with false when conditions that trigger a stale block, so // a new block template can be generated. When the return is // true a solution was found, so submit the solved block. - if m.solveBlock(template.block, curHeight+1, ticker, nil) { - block := btcutil.NewBlock(template.block) + if m.solveBlock(template.Block, curHeight+1, ticker, nil) { + block := btcutil.NewBlock(template.Block) m.submitBlock(block) blockHashes[i] = block.Sha() i++ diff --git a/mining.go b/mining.go index 8314099a..4359fa47 100644 --- a/mining.go +++ b/mining.go @@ -156,11 +156,30 @@ func newTxPriorityQueue(reserve int, sortByFee bool) *txPriorityQueue { // details about the fees and the number of signature operations for each // transaction in the block. type BlockTemplate struct { - block *wire.MsgBlock - fees []int64 - sigOpCounts []int64 - height int32 - validPayAddress bool + // Block is a block that is ready to be solved by miners. Thus, it is + // completely valid with the exception of satisfying the proof-of-work + // requirement. + Block *wire.MsgBlock + + // Fees contains the amount of fees each transaction in the generated + // template pays in base units. Since the first transaction is the + // coinbase, the first entry (offset 0) will contain the negative of the + // sum of the fees of all other transactions. + Fees []int64 + + // SigOpCounts contains the number of signature operations each + // transaction in the generated template performs. + SigOpCounts []int64 + + // Height is the height at which the block template connects to the main + // chain. + Height int32 + + // ValidPayAddress indicates whether or not the template coinbase pays + // to an address or is redeemable by anyone. See the documentation on + // NewBlockTemplate for details on which this can be useful to generate + // templates without a coinbase payment address. + ValidPayAddress bool } // mergeTxStore adds all of the transactions in txStoreB to txStoreA. The @@ -750,11 +769,11 @@ mempoolLoop: blockSize, blockchain.CompactToBig(msgBlock.Header.Bits)) return &BlockTemplate{ - block: &msgBlock, - fees: txFees, - sigOpCounts: txSigOpCounts, - height: nextBlockHeight, - validPayAddress: payToAddress != nil, + Block: &msgBlock, + Fees: txFees, + SigOpCounts: txSigOpCounts, + Height: nextBlockHeight, + ValidPayAddress: payToAddress != nil, }, nil } diff --git a/rpcserver.go b/rpcserver.go index 6194e672..8a4d3b8e 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1534,7 +1534,7 @@ func (state *gbtWorkState) updateBlockTemplate(s *rpcServer, useCoinbaseValue bo "template: "+err.Error(), "") } template = blkTemplate - msgBlock = template.block + msgBlock = template.Block targetDifficulty = fmt.Sprintf("%064x", blockchain.CompactToBig(msgBlock.Header.Bits)) @@ -1577,7 +1577,7 @@ func (state *gbtWorkState) updateBlockTemplate(s *rpcServer, useCoinbaseValue bo // template if it doesn't already have one. Since this requires // mining addresses to be specified via the config, an error is // returned if none have been specified. - if !useCoinbaseValue && !template.validPayAddress { + if !useCoinbaseValue && !template.ValidPayAddress { // Choose a payment address at random. payToAddr := cfg.miningAddrs[rand.Intn(len(cfg.miningAddrs))] @@ -1588,17 +1588,17 @@ func (state *gbtWorkState) updateBlockTemplate(s *rpcServer, useCoinbaseValue bo context := "Failed to create pay-to-addr script" return internalRPCError(err.Error(), context) } - template.block.Transactions[0].TxOut[0].PkScript = pkScript - template.validPayAddress = true + template.Block.Transactions[0].TxOut[0].PkScript = pkScript + template.ValidPayAddress = true // Update the merkle root. - block := btcutil.NewBlock(template.block) + block := btcutil.NewBlock(template.Block) merkles := blockchain.BuildMerkleTreeStore(block.Transactions()) - template.block.Header.MerkleRoot = *merkles[len(merkles)-1] + template.Block.Header.MerkleRoot = *merkles[len(merkles)-1] } // Set locals for convenience. - msgBlock = template.block + msgBlock = template.Block targetDifficulty = fmt.Sprintf("%064x", blockchain.CompactToBig(msgBlock.Header.Bits)) @@ -1627,7 +1627,7 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld // after the template is generated, but it's important to avoid serving // invalid block templates. template := state.template - msgBlock := template.block + msgBlock := template.Block header := &msgBlock.Header adjustedTime := state.timeSource.AdjustedTime() maxTime := adjustedTime.Add(time.Second * blockchain.MaxTimeOffsetSeconds) @@ -1684,8 +1684,8 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld Data: hex.EncodeToString(txBuf.Bytes()), Hash: txHash.String(), Depends: depends, - Fee: template.fees[i], - SigOps: template.sigOpCounts[i], + Fee: template.Fees[i], + SigOps: template.SigOpCounts[i], } transactions = append(transactions, resultTx) } @@ -1699,7 +1699,7 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld reply := btcjson.GetBlockTemplateResult{ Bits: strconv.FormatInt(int64(header.Bits), 16), CurTime: header.Timestamp.Unix(), - Height: int64(template.height), + Height: int64(template.Height), PreviousHash: header.PrevBlock.String(), SigOpLimit: blockchain.MaxSigOpsPerBlock, SizeLimit: wire.MaxBlockPayload, @@ -1720,7 +1720,7 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld } else { // Ensure the template has a valid payment address associated // with it when a full coinbase is requested. - if !template.validPayAddress { + if !template.ValidPayAddress { return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCInternal.Code, Message: "A coinbase transaction has been " + @@ -1742,8 +1742,8 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld Data: hex.EncodeToString(txBuf.Bytes()), Hash: tx.TxSha().String(), Depends: []int64{}, - Fee: template.fees[0], - SigOps: template.sigOpCounts[0], + Fee: template.Fees[0], + SigOps: template.SigOpCounts[0], } reply.CoinbaseTxn = &resultTx @@ -1791,7 +1791,7 @@ func handleGetBlockTemplateLongPoll(s *rpcServer, longPollID string, useCoinbase // Return the block template now if the specific block template // identified by the long poll ID no longer matches the current block // template as this means the provided template is stale. - prevTemplateHash := &state.template.block.Header.PrevBlock + prevTemplateHash := &state.template.Block.Header.PrevBlock if !prevHash.IsEqual(prevTemplateHash) || lastGenerated != state.lastGenerated.Unix() { @@ -1839,7 +1839,7 @@ func handleGetBlockTemplateLongPoll(s *rpcServer, longPollID string, useCoinbase // Include whether or not it is valid to submit work against the old // block template depending on whether or not a solution has already // been found and added to the block chain. - submitOld := prevHash.IsEqual(&state.template.block.Header.PrevBlock) + submitOld := prevHash.IsEqual(&state.template.Block.Header.PrevBlock) result, err := state.blockTemplateResult(useCoinbaseValue, &submitOld) if err != nil { return nil, err @@ -2723,7 +2723,7 @@ func handleGetWorkRequest(s *rpcServer) (interface{}, error) { context := "Failed to create new block template" return nil, internalRPCError(err.Error(), context) } - msgBlock = template.block + msgBlock = template.Block // Update work state to ensure another block template isn't // generated until needed.