func (b *BlockChain) CheckBlockHeaderContextEx(header *wire.BlockHeader, prevNode *blockNode, flags BehaviorFlags) error {
	return b.checkBlockHeaderContext(header, prevNode, flags)
}
CheckBlockHeaderContextEx makes the internal checkBlockHeaderContext
function available to the test package.
package blockchain
import (
	"fmt"
	"os"
	"path/filepath"
	"sort"
	"time"
	"github.com/HcashOrg/hcashd/chaincfg"
	"github.com/HcashOrg/hcashd/chaincfg/chainhash"
	"github.com/HcashOrg/hcashd/database"
	"github.com/HcashOrg/hcashd/txscript"
	"github.com/HcashOrg/hcashd/wire"
	"github.com/HcashOrg/hcashutil"
	_ "github.com/HcashOrg/hcashd/database/ffldb"
)
func recalculateMsgBlockMerkleRootsSize(msgBlock *wire.MsgBlock) {
	tempBlock := hcashutil.NewBlock(msgBlock)
	merkles := BuildMerkleTreeStore(tempBlock.Transactions(), false)
	merklesStake := BuildMerkleTreeStore(tempBlock.STransactions(), false)
	msgBlock.Header.MerkleRoot = *merkles[len(merkles)-1]
	msgBlock.Header.StakeRoot = *merklesStake[len(merklesStake)-1]
	msgBlock.Header.Size = uint32(msgBlock.SerializeSize())
}
func fileExists(name string) bool {
	if _, err := os.Stat(name); err != nil {
		if os.IsNotExist(err) {
			return false
		}
	}
	return true
}
func isSupportedDbType(dbType string) bool {
	supportedDrivers := database.SupportedDrivers()
	for _, driver := range supportedDrivers {
		if dbType == driver {
			return true
		}
	}
	return false
}
func SetupTestChain(dbName string, params *chaincfg.Params) (*BlockChain, func(), error) {
	if !isSupportedDbType(testDbType) {
		return nil, nil, fmt.Errorf("unsupported db type %v", testDbType)
	}
	var db database.DB
	var teardown func()
	if testDbType == "memdb" {
		ndb, err := database.Create(testDbType)
		if err != nil {
			return nil, nil, fmt.Errorf("error creating db: %v", err)
		}
		db = ndb
		teardown = func() {
			db.Close()
		}
	} else {
		if !fileExists(testDbRoot) {
			if err := os.MkdirAll(testDbRoot, 0700); err != nil {
				err := fmt.Errorf("unable to create test db "+
					"root: %v", err)
				return nil, nil, err
			}
		}
		dbPath := filepath.Join(testDbRoot, dbName)
		_ = os.RemoveAll(dbPath)
		ndb, err := database.Create(testDbType, dbPath, blockDataNet)
		if err != nil {
			return nil, nil, fmt.Errorf("error creating db: %v", err)
		}
		db = ndb
		teardown = func() {
			db.Close()
			os.RemoveAll(dbPath)
			os.RemoveAll(testDbRoot)
		}
	}
	paramsCopy := *params
	chain, err := New(&Config{
		DB:          db,
		ChainParams: &paramsCopy,
		TimeSource:  NewMedianTime(),
		SigCache:    txscript.NewSigCache(1000),
	})
	if err != nil {
		teardown()
		err := fmt.Errorf("failed to create chain instance: %v", err)
		return nil, nil, err
	}
	return chain, teardown, nil
}
func FakeBlock(blockVersion int32, height int64, stakeVersion uint32) *hcashutil.Block {
	header := wire.BlockHeader{
		Version:      blockVersion,
		Height:       uint32(height),
		Nonce:        0,
		StakeVersion: stakeVersion,
	}
	msgBlock := &wire.MsgBlock{
		Header: header,
	}
	return hcashutil.NewBlock(msgBlock)
}
func FakeBlockFromHeader(header *wire.BlockHeader) *hcashutil.Block {
	msgBlock := &wire.MsgBlock{
		Header: *header,
	}
	return hcashutil.NewBlock(msgBlock)
}