mirror of
https://github.com/btcsuite/btcd.git
synced 2024-11-19 01:40:07 +01:00
fullblocktests, testhelper: move solveBlock to testhelper
solveBlock is moved to testhelper and is exported. This is done so that the code can be reused without introducing import cycles. The testing code to be added in alter commits for invalidateblock and reconsider block will use SolveBlock.
This commit is contained in:
parent
337d7f6be8
commit
d4644dff10
@ -14,7 +14,6 @@ import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
@ -303,71 +302,6 @@ func calcMerkleRoot(txns []*wire.MsgTx) chainhash.Hash {
|
||||
return blockchain.CalcMerkleRoot(utilTxns, false)
|
||||
}
|
||||
|
||||
// solveBlock attempts to find a nonce which makes the passed block header hash
|
||||
// to a value less than the target difficulty. When a successful solution is
|
||||
// found true is returned and the nonce field of the passed header is updated
|
||||
// with the solution. False is returned if no solution exists.
|
||||
//
|
||||
// NOTE: This function will never solve blocks with a nonce of 0. This is done
|
||||
// so the 'nextBlock' function can properly detect when a nonce was modified by
|
||||
// a munge function.
|
||||
func solveBlock(header *wire.BlockHeader) bool {
|
||||
// sbResult is used by the solver goroutines to send results.
|
||||
type sbResult struct {
|
||||
found bool
|
||||
nonce uint32
|
||||
}
|
||||
|
||||
// solver accepts a block header and a nonce range to test. It is
|
||||
// intended to be run as a goroutine.
|
||||
targetDifficulty := blockchain.CompactToBig(header.Bits)
|
||||
quit := make(chan bool)
|
||||
results := make(chan sbResult)
|
||||
solver := func(hdr wire.BlockHeader, startNonce, stopNonce uint32) {
|
||||
// We need to modify the nonce field of the header, so make sure
|
||||
// we work with a copy of the original header.
|
||||
for i := startNonce; i >= startNonce && i <= stopNonce; i++ {
|
||||
select {
|
||||
case <-quit:
|
||||
return
|
||||
default:
|
||||
hdr.Nonce = i
|
||||
hash := hdr.BlockHash()
|
||||
if blockchain.HashToBig(&hash).Cmp(
|
||||
targetDifficulty) <= 0 {
|
||||
|
||||
results <- sbResult{true, i}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
results <- sbResult{false, 0}
|
||||
}
|
||||
|
||||
startNonce := uint32(1)
|
||||
stopNonce := uint32(math.MaxUint32)
|
||||
numCores := uint32(runtime.NumCPU())
|
||||
noncesPerCore := (stopNonce - startNonce) / numCores
|
||||
for i := uint32(0); i < numCores; i++ {
|
||||
rangeStart := startNonce + (noncesPerCore * i)
|
||||
rangeStop := startNonce + (noncesPerCore * (i + 1)) - 1
|
||||
if i == numCores-1 {
|
||||
rangeStop = stopNonce
|
||||
}
|
||||
go solver(*header, rangeStart, rangeStop)
|
||||
}
|
||||
for i := uint32(0); i < numCores; i++ {
|
||||
result := <-results
|
||||
if result.found {
|
||||
close(quit)
|
||||
header.Nonce = result.nonce
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// additionalCoinbase returns a function that itself takes a block and
|
||||
// modifies it by adding the provided amount to coinbase subsidy.
|
||||
func additionalCoinbase(amount btcutil.Amount) func(*wire.MsgBlock) {
|
||||
@ -523,7 +457,7 @@ func (g *testGenerator) nextBlock(blockName string, spend *testhelper.SpendableO
|
||||
|
||||
// Only solve the block if the nonce wasn't manually changed by a munge
|
||||
// function.
|
||||
if block.Header.Nonce == curNonce && !solveBlock(&block.Header) {
|
||||
if block.Header.Nonce == curNonce && !testhelper.SolveBlock(&block.Header) {
|
||||
panic(fmt.Sprintf("Unable to solve block at height %d",
|
||||
nextHeight))
|
||||
}
|
||||
|
@ -1,6 +1,10 @@
|
||||
package testhelper
|
||||
|
||||
import (
|
||||
"math"
|
||||
"runtime"
|
||||
|
||||
"github.com/btcsuite/btcd/blockchain/internal/workmath"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
)
|
||||
@ -29,3 +33,68 @@ func MakeSpendableOutForTx(tx *wire.MsgTx, txOutIndex uint32) SpendableOut {
|
||||
func MakeSpendableOut(block *wire.MsgBlock, txIndex, txOutIndex uint32) SpendableOut {
|
||||
return MakeSpendableOutForTx(block.Transactions[txIndex], txOutIndex)
|
||||
}
|
||||
|
||||
// SolveBlock attempts to find a nonce which makes the passed block header hash
|
||||
// to a value less than the target difficulty. When a successful solution is
|
||||
// found true is returned and the nonce field of the passed header is updated
|
||||
// with the solution. False is returned if no solution exists.
|
||||
//
|
||||
// NOTE: This function will never solve blocks with a nonce of 0. This is done
|
||||
// so the 'nextBlock' function can properly detect when a nonce was modified by
|
||||
// a munge function.
|
||||
func SolveBlock(header *wire.BlockHeader) bool {
|
||||
// sbResult is used by the solver goroutines to send results.
|
||||
type sbResult struct {
|
||||
found bool
|
||||
nonce uint32
|
||||
}
|
||||
|
||||
// solver accepts a block header and a nonce range to test. It is
|
||||
// intended to be run as a goroutine.
|
||||
targetDifficulty := workmath.CompactToBig(header.Bits)
|
||||
quit := make(chan bool)
|
||||
results := make(chan sbResult)
|
||||
solver := func(hdr wire.BlockHeader, startNonce, stopNonce uint32) {
|
||||
// We need to modify the nonce field of the header, so make sure
|
||||
// we work with a copy of the original header.
|
||||
for i := startNonce; i >= startNonce && i <= stopNonce; i++ {
|
||||
select {
|
||||
case <-quit:
|
||||
return
|
||||
default:
|
||||
hdr.Nonce = i
|
||||
hash := hdr.BlockHash()
|
||||
if workmath.HashToBig(&hash).Cmp(
|
||||
targetDifficulty) <= 0 {
|
||||
|
||||
results <- sbResult{true, i}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
results <- sbResult{false, 0}
|
||||
}
|
||||
|
||||
startNonce := uint32(1)
|
||||
stopNonce := uint32(math.MaxUint32)
|
||||
numCores := uint32(runtime.NumCPU())
|
||||
noncesPerCore := (stopNonce - startNonce) / numCores
|
||||
for i := uint32(0); i < numCores; i++ {
|
||||
rangeStart := startNonce + (noncesPerCore * i)
|
||||
rangeStop := startNonce + (noncesPerCore * (i + 1)) - 1
|
||||
if i == numCores-1 {
|
||||
rangeStop = stopNonce
|
||||
}
|
||||
go solver(*header, rangeStart, rangeStop)
|
||||
}
|
||||
for i := uint32(0); i < numCores; i++ {
|
||||
result := <-results
|
||||
if result.found {
|
||||
close(quit)
|
||||
header.Nonce = result.nonce
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user