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. // checkpoint. This is primarily used for headers-first mode.
BFFastAdd BehaviorFlags = 1 << iota 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 is a convenience value to specifically indicate no flags.
BFNone BehaviorFlags = 0 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. // 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 { if err != nil {
return false, err return false, err
} }

View file

@ -268,10 +268,15 @@ func CheckTransactionSanity(tx *btcutil.Tx) error {
return nil 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 // difficulty is in min/max range and that the block hash is less than the
// target difficulty as claimed. // 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. // The target difficulty must be larger than zero.
target := CompactToBig(block.MsgBlock().Header.Bits) target := CompactToBig(block.MsgBlock().Header.Bits)
if target.Sign() <= 0 { if target.Sign() <= 0 {
@ -287,21 +292,32 @@ func CheckProofOfWork(block *btcutil.Block, powLimit *big.Int) error {
return ruleError(ErrUnexpectedDifficulty, str) return ruleError(ErrUnexpectedDifficulty, str)
} }
// The block hash must be less than the claimed target. // The block hash must be less than the claimed target unless the flag
blockHash, err := block.Sha() // to avoid proof of work checks is set.
if err != nil { if flags&BFNoPoWCheck != BFNoPoWCheck {
return err // The block hash must be less than the claimed target.
} blockHash, err := block.Sha()
hashNum := ShaHashToBig(blockHash) if err != nil {
if hashNum.Cmp(target) > 0 { return err
str := fmt.Sprintf("block hash of %064x is higher than "+ }
"expected max of %064x", hashNum, target) hashNum := ShaHashToBig(blockHash)
return ruleError(ErrHighHash, str) 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 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 // CountSigOps returns the number of signature operations for all transaction
// input and output scripts in the provided transaction. This uses the // input and output scripts in the provided transaction. This uses the
// quicker, but imprecise, signature operation counting mechanism from // 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 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. // 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 // NOTE: bitcoind does size limits checking here, but the size limits
// have already been checked by btcwire for incoming blocks. Also, // have already been checked by btcwire for incoming blocks. Also,
// btcwire checks the size limits on send too, so there is no need // 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 // 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 // and the block hash is less than the target value described by the
// bits. // bits.
err := CheckProofOfWork(block, powLimit) err := checkProofOfWork(block, powLimit, flags)
if err != nil { if err != nil {
return err return err
} }
@ -506,6 +525,12 @@ func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int) error {
return nil 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 // checkSerializedHeight checks if the signature script in the passed
// transaction starts with the serialized block height of wantHeight. // transaction starts with the serialized block height of wantHeight.
func checkSerializedHeight(coinbaseTx *btcutil.Tx, wantHeight int64) error { func checkSerializedHeight(coinbaseTx *btcutil.Tx, wantHeight int64) error {