mining: Export block template fields. (#659)
This simply exports and adds some comments to the fields of the BlockTemplate struct. This is primarily being done as a step toward being able to separate the mining code into its own package, but also it makes sense on its own because code that requests new block template necessarily examines the returned fields which implies they should be exported.
This commit is contained in:
parent
cab74feb59
commit
a3fa066745
3 changed files with 50 additions and 31 deletions
|
@ -318,8 +318,8 @@ out:
|
||||||
// with false when conditions that trigger a stale block, so
|
// with false when conditions that trigger a stale block, so
|
||||||
// a new block template can be generated. When the return is
|
// a new block template can be generated. When the return is
|
||||||
// true a solution was found, so submit the solved block.
|
// true a solution was found, so submit the solved block.
|
||||||
if m.solveBlock(template.block, curHeight+1, ticker, quit) {
|
if m.solveBlock(template.Block, curHeight+1, ticker, quit) {
|
||||||
block := btcutil.NewBlock(template.block)
|
block := btcutil.NewBlock(template.Block)
|
||||||
m.submitBlock(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
|
// with false when conditions that trigger a stale block, so
|
||||||
// a new block template can be generated. When the return is
|
// a new block template can be generated. When the return is
|
||||||
// true a solution was found, so submit the solved block.
|
// true a solution was found, so submit the solved block.
|
||||||
if m.solveBlock(template.block, curHeight+1, ticker, nil) {
|
if m.solveBlock(template.Block, curHeight+1, ticker, nil) {
|
||||||
block := btcutil.NewBlock(template.block)
|
block := btcutil.NewBlock(template.Block)
|
||||||
m.submitBlock(block)
|
m.submitBlock(block)
|
||||||
blockHashes[i] = block.Sha()
|
blockHashes[i] = block.Sha()
|
||||||
i++
|
i++
|
||||||
|
|
39
mining.go
39
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
|
// details about the fees and the number of signature operations for each
|
||||||
// transaction in the block.
|
// transaction in the block.
|
||||||
type BlockTemplate struct {
|
type BlockTemplate struct {
|
||||||
block *wire.MsgBlock
|
// Block is a block that is ready to be solved by miners. Thus, it is
|
||||||
fees []int64
|
// completely valid with the exception of satisfying the proof-of-work
|
||||||
sigOpCounts []int64
|
// requirement.
|
||||||
height int32
|
Block *wire.MsgBlock
|
||||||
validPayAddress bool
|
|
||||||
|
// 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
|
// mergeTxStore adds all of the transactions in txStoreB to txStoreA. The
|
||||||
|
@ -750,11 +769,11 @@ mempoolLoop:
|
||||||
blockSize, blockchain.CompactToBig(msgBlock.Header.Bits))
|
blockSize, blockchain.CompactToBig(msgBlock.Header.Bits))
|
||||||
|
|
||||||
return &BlockTemplate{
|
return &BlockTemplate{
|
||||||
block: &msgBlock,
|
Block: &msgBlock,
|
||||||
fees: txFees,
|
Fees: txFees,
|
||||||
sigOpCounts: txSigOpCounts,
|
SigOpCounts: txSigOpCounts,
|
||||||
height: nextBlockHeight,
|
Height: nextBlockHeight,
|
||||||
validPayAddress: payToAddress != nil,
|
ValidPayAddress: payToAddress != nil,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
34
rpcserver.go
34
rpcserver.go
|
@ -1534,7 +1534,7 @@ func (state *gbtWorkState) updateBlockTemplate(s *rpcServer, useCoinbaseValue bo
|
||||||
"template: "+err.Error(), "")
|
"template: "+err.Error(), "")
|
||||||
}
|
}
|
||||||
template = blkTemplate
|
template = blkTemplate
|
||||||
msgBlock = template.block
|
msgBlock = template.Block
|
||||||
targetDifficulty = fmt.Sprintf("%064x",
|
targetDifficulty = fmt.Sprintf("%064x",
|
||||||
blockchain.CompactToBig(msgBlock.Header.Bits))
|
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
|
// template if it doesn't already have one. Since this requires
|
||||||
// mining addresses to be specified via the config, an error is
|
// mining addresses to be specified via the config, an error is
|
||||||
// returned if none have been specified.
|
// returned if none have been specified.
|
||||||
if !useCoinbaseValue && !template.validPayAddress {
|
if !useCoinbaseValue && !template.ValidPayAddress {
|
||||||
// Choose a payment address at random.
|
// Choose a payment address at random.
|
||||||
payToAddr := cfg.miningAddrs[rand.Intn(len(cfg.miningAddrs))]
|
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"
|
context := "Failed to create pay-to-addr script"
|
||||||
return internalRPCError(err.Error(), context)
|
return internalRPCError(err.Error(), context)
|
||||||
}
|
}
|
||||||
template.block.Transactions[0].TxOut[0].PkScript = pkScript
|
template.Block.Transactions[0].TxOut[0].PkScript = pkScript
|
||||||
template.validPayAddress = true
|
template.ValidPayAddress = true
|
||||||
|
|
||||||
// Update the merkle root.
|
// Update the merkle root.
|
||||||
block := btcutil.NewBlock(template.block)
|
block := btcutil.NewBlock(template.Block)
|
||||||
merkles := blockchain.BuildMerkleTreeStore(block.Transactions())
|
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.
|
// Set locals for convenience.
|
||||||
msgBlock = template.block
|
msgBlock = template.Block
|
||||||
targetDifficulty = fmt.Sprintf("%064x",
|
targetDifficulty = fmt.Sprintf("%064x",
|
||||||
blockchain.CompactToBig(msgBlock.Header.Bits))
|
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
|
// after the template is generated, but it's important to avoid serving
|
||||||
// invalid block templates.
|
// invalid block templates.
|
||||||
template := state.template
|
template := state.template
|
||||||
msgBlock := template.block
|
msgBlock := template.Block
|
||||||
header := &msgBlock.Header
|
header := &msgBlock.Header
|
||||||
adjustedTime := state.timeSource.AdjustedTime()
|
adjustedTime := state.timeSource.AdjustedTime()
|
||||||
maxTime := adjustedTime.Add(time.Second * blockchain.MaxTimeOffsetSeconds)
|
maxTime := adjustedTime.Add(time.Second * blockchain.MaxTimeOffsetSeconds)
|
||||||
|
@ -1684,8 +1684,8 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld
|
||||||
Data: hex.EncodeToString(txBuf.Bytes()),
|
Data: hex.EncodeToString(txBuf.Bytes()),
|
||||||
Hash: txHash.String(),
|
Hash: txHash.String(),
|
||||||
Depends: depends,
|
Depends: depends,
|
||||||
Fee: template.fees[i],
|
Fee: template.Fees[i],
|
||||||
SigOps: template.sigOpCounts[i],
|
SigOps: template.SigOpCounts[i],
|
||||||
}
|
}
|
||||||
transactions = append(transactions, resultTx)
|
transactions = append(transactions, resultTx)
|
||||||
}
|
}
|
||||||
|
@ -1699,7 +1699,7 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld
|
||||||
reply := btcjson.GetBlockTemplateResult{
|
reply := btcjson.GetBlockTemplateResult{
|
||||||
Bits: strconv.FormatInt(int64(header.Bits), 16),
|
Bits: strconv.FormatInt(int64(header.Bits), 16),
|
||||||
CurTime: header.Timestamp.Unix(),
|
CurTime: header.Timestamp.Unix(),
|
||||||
Height: int64(template.height),
|
Height: int64(template.Height),
|
||||||
PreviousHash: header.PrevBlock.String(),
|
PreviousHash: header.PrevBlock.String(),
|
||||||
SigOpLimit: blockchain.MaxSigOpsPerBlock,
|
SigOpLimit: blockchain.MaxSigOpsPerBlock,
|
||||||
SizeLimit: wire.MaxBlockPayload,
|
SizeLimit: wire.MaxBlockPayload,
|
||||||
|
@ -1720,7 +1720,7 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld
|
||||||
} else {
|
} else {
|
||||||
// Ensure the template has a valid payment address associated
|
// Ensure the template has a valid payment address associated
|
||||||
// with it when a full coinbase is requested.
|
// with it when a full coinbase is requested.
|
||||||
if !template.validPayAddress {
|
if !template.ValidPayAddress {
|
||||||
return nil, &btcjson.RPCError{
|
return nil, &btcjson.RPCError{
|
||||||
Code: btcjson.ErrRPCInternal.Code,
|
Code: btcjson.ErrRPCInternal.Code,
|
||||||
Message: "A coinbase transaction has been " +
|
Message: "A coinbase transaction has been " +
|
||||||
|
@ -1742,8 +1742,8 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld
|
||||||
Data: hex.EncodeToString(txBuf.Bytes()),
|
Data: hex.EncodeToString(txBuf.Bytes()),
|
||||||
Hash: tx.TxSha().String(),
|
Hash: tx.TxSha().String(),
|
||||||
Depends: []int64{},
|
Depends: []int64{},
|
||||||
Fee: template.fees[0],
|
Fee: template.Fees[0],
|
||||||
SigOps: template.sigOpCounts[0],
|
SigOps: template.SigOpCounts[0],
|
||||||
}
|
}
|
||||||
|
|
||||||
reply.CoinbaseTxn = &resultTx
|
reply.CoinbaseTxn = &resultTx
|
||||||
|
@ -1791,7 +1791,7 @@ func handleGetBlockTemplateLongPoll(s *rpcServer, longPollID string, useCoinbase
|
||||||
// Return the block template now if the specific block template
|
// Return the block template now if the specific block template
|
||||||
// identified by the long poll ID no longer matches the current block
|
// identified by the long poll ID no longer matches the current block
|
||||||
// template as this means the provided template is stale.
|
// 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) ||
|
if !prevHash.IsEqual(prevTemplateHash) ||
|
||||||
lastGenerated != state.lastGenerated.Unix() {
|
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
|
// Include whether or not it is valid to submit work against the old
|
||||||
// block template depending on whether or not a solution has already
|
// block template depending on whether or not a solution has already
|
||||||
// been found and added to the block chain.
|
// 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)
|
result, err := state.blockTemplateResult(useCoinbaseValue, &submitOld)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -2723,7 +2723,7 @@ func handleGetWorkRequest(s *rpcServer) (interface{}, error) {
|
||||||
context := "Failed to create new block template"
|
context := "Failed to create new block template"
|
||||||
return nil, internalRPCError(err.Error(), context)
|
return nil, internalRPCError(err.Error(), context)
|
||||||
}
|
}
|
||||||
msgBlock = template.block
|
msgBlock = template.Block
|
||||||
|
|
||||||
// Update work state to ensure another block template isn't
|
// Update work state to ensure another block template isn't
|
||||||
// generated until needed.
|
// generated until needed.
|
||||||
|
|
Loading…
Reference in a new issue