Add a new behavior flag to disable the pow check.

This commit adds a new behavior flag, BFNoPoWCheck which allows the caller
to indicate the check which ensures a block hashes to a value less than
required target should not be performed.
This commit is contained in:
Dave Collins 2014-06-26 15:50:13 -05:00
parent 67394ec45d
commit ad275b34a8
2 changed files with 46 additions and 16 deletions

View file

@ -21,6 +21,11 @@ const (
// checkpoint. This is primarily used for headers-first mode.
BFFastAdd BehaviorFlags = 1 << iota
// BFNoPoWCheck may be set to indicate the proof of work check which
// ensures a block hashes to a value less than the required target will
// not be performed.
BFNoPoWCheck
// BFNone is a convenience value to specifically indicate no flags.
BFNone BehaviorFlags = 0
)
@ -125,7 +130,7 @@ func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bo
}
// Perform preliminary sanity checks on the block and its transactions.
err = CheckBlockSanity(block, b.netParams.PowLimit)
err = checkBlockSanity(block, b.netParams.PowLimit, flags)
if err != nil {
return false, err
}

View file

@ -268,10 +268,15 @@ func CheckTransactionSanity(tx *btcutil.Tx) error {
return nil
}
// CheckProofOfWork ensures the block header bits which indicate the target
// checkProofOfWork ensures the block header bits which indicate the target
// difficulty is in min/max range and that the block hash is less than the
// target difficulty as claimed.
func CheckProofOfWork(block *btcutil.Block, powLimit *big.Int) error {
//
//
// The flags modify the behavior of this function as follows:
// - BFNoPoWCheck: The check to ensure the block hash is less than the target
// difficulty is not performed.
func checkProofOfWork(block *btcutil.Block, powLimit *big.Int, flags BehaviorFlags) error {
// The target difficulty must be larger than zero.
target := CompactToBig(block.MsgBlock().Header.Bits)
if target.Sign() <= 0 {
@ -287,21 +292,32 @@ func CheckProofOfWork(block *btcutil.Block, powLimit *big.Int) error {
return ruleError(ErrUnexpectedDifficulty, str)
}
// The block hash must be less than the claimed target.
blockHash, err := block.Sha()
if err != nil {
return err
}
hashNum := ShaHashToBig(blockHash)
if hashNum.Cmp(target) > 0 {
str := fmt.Sprintf("block hash of %064x is higher than "+
"expected max of %064x", hashNum, target)
return ruleError(ErrHighHash, str)
// The block hash must be less than the claimed target unless the flag
// to avoid proof of work checks is set.
if flags&BFNoPoWCheck != BFNoPoWCheck {
// The block hash must be less than the claimed target.
blockHash, err := block.Sha()
if err != nil {
return err
}
hashNum := ShaHashToBig(blockHash)
if hashNum.Cmp(target) > 0 {
str := fmt.Sprintf("block hash of %064x is higher than "+
"expected max of %064x", hashNum, target)
return ruleError(ErrHighHash, str)
}
}
return nil
}
// CheckProofOfWork ensures the block header bits which indicate the target
// difficulty is in min/max range and that the block hash is less than the
// target difficulty as claimed.
func CheckProofOfWork(block *btcutil.Block, powLimit *big.Int) error {
return checkProofOfWork(block, powLimit, BFNone)
}
// CountSigOps returns the number of signature operations for all transaction
// input and output scripts in the provided transaction. This uses the
// quicker, but imprecise, signature operation counting mechanism from
@ -392,9 +408,12 @@ func CountP2SHSigOps(tx *btcutil.Tx, isCoinBaseTx bool, txStore TxStore) (int, e
return totalSigOps, nil
}
// CheckBlockSanity performs some preliminary checks on a block to ensure it is
// checkBlockSanity performs some preliminary checks on a block to ensure it is
// sane before continuing with block processing. These checks are context free.
func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error {
//
// The flags do not modify the behavior of this function directly, however they
// are needed to pass along to checkProofOfWork.
func checkBlockSanity(block *btcutil.Block, powLimit *big.Int, flags BehaviorFlags) error {
// NOTE: bitcoind does size limits checking here, but the size limits
// have already been checked by btcwire for incoming blocks. Also,
// btcwire checks the size limits on send too, so there is no need
@ -403,7 +422,7 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error {
// Ensure the proof of work bits in the block header is in min/max range
// and the block hash is less than the target value described by the
// bits.
err := CheckProofOfWork(block, powLimit)
err := checkProofOfWork(block, powLimit, flags)
if err != nil {
return err
}
@ -506,6 +525,12 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error {
return nil
}
// CheckBlockSanity performs some preliminary checks on a block to ensure it is
// sane before continuing with block processing. These checks are context free.
func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error {
return checkBlockSanity(block, powLimit, BFNone)
}
// checkSerializedHeight checks if the signature script in the passed
// transaction starts with the serialized block height of wantHeight.
func checkSerializedHeight(coinbaseTx *btcutil.Tx, wantHeight int64) error {