Documentation
¶
Overview ¶
Package blockchain implements bitcoin block handling and chain selection rules.
The bitcoin block handling and chain selection rules are an integral, and quite likely the most important, part of bitcoin. Unfortunately, at the time of this writing, these rules are also largely undocumented and had to be ascertained from the bitcoind source code. At its core, bitcoin is a distributed consensus of which blocks are valid and which ones will comprise the main block chain (public ledger) that ultimately determines accepted transactions, so it is extremely important that fully validating nodes agree on all rules.
At a high level, this package provides support for inserting new blocks into the block chain according to the aforementioned rules. It includes functionality such as rejecting duplicate blocks, ensuring blocks and transactions follow all rules, orphan handling, and best chain selection along with reorganization.
Since this package does not deal with other bitcoin specifics such as network communication or wallets, it provides a notification system which gives the caller a high level of flexibility in how they want to react to certain events such as orphan blocks which need their parents requested and newly connected main chain blocks which might result in wallet updates.
Bitcoin Chain Processing Overview ¶
Before a block is allowed into the block chain, it must go through an intensive series of validation rules. The following list serves as a general outline of those rules to provide some intuition into what is going on under the hood, but is by no means exhaustive:
- Reject duplicate blocks
- Perform a series of sanity checks on the block and its transactions such as verifying proof of work, timestamps, number and character of transactions, transaction amounts, script complexity, and merkle root calculations
- Compare the block against predetermined checkpoints for expected timestamps and difficulty based on elapsed time since the checkpoint
- Save the most recent orphan blocks for a limited time in case their parent blocks become available
- Stop processing if the block is an orphan as the rest of the processing depends on the block's position within the block chain
- Perform a series of more thorough checks that depend on the block's position within the block chain such as verifying block difficulties adhere to difficulty retarget rules, timestamps are after the median of the last several blocks, all transactions are finalized, checkpoint blocks match, and block versions are in line with the previous blocks
- Determine how the block fits into the chain and perform different actions accordingly in order to ensure any side chains which have higher difficulty than the main chain become the new main chain
- When a block is being connected to the main chain (either through reorganization of a side chain to the main chain or just extending the main chain), perform further checks on the block's transactions such as verifying transaction duplicates, script complexity for the combination of connected scripts, coinbase maturity, double spends, and connected transaction values
- Run the transaction scripts to verify the spender is allowed to spend the coins
- Insert the block into the block database
Errors ¶
Errors returned by this package are either the raw errors provided by underlying calls or of type blockchain.RuleError. This allows the caller to differentiate between unexpected errors, such as database errors, versus errors due to rule violations through type assertions. In addition, callers can programmatically determine the specific rule violation by examining the ErrorCode field of the type asserted blockchain.RuleError.
Bitcoin Improvement Proposals ¶
This package includes spec changes outlined by the following BIPs:
BIP0016 (https://en.bitcoin.it/wiki/BIP_0016) BIP0030 (https://en.bitcoin.it/wiki/BIP_0030) BIP0034 (https://en.bitcoin.it/wiki/BIP_0034)
Index ¶
- Constants
- Variables
- func BbFetchVersion(dbTx database.Tx, key []byte) uint32
- func BigToCompact(n *big.Int) uint32
- func BlockIndexKey(blockHash *chainhash.Hash, blockHeight uint32) []byte
- func BlockToOrphan(block *btcutil.Block) chainutil.Orphaned
- func BuildMerkleTreeStore(transactions []*btcutil.Tx, witness bool, version uint32) []*chainhash.Hash
- func CalcBlockSubsidy(height int32, chainParams *chaincfg.Params, prevPows uint) int64
- func CalcWork(bits uint32) *big.Int
- func CheckAdditionalDefinitions(tx *btcutil.Tx, txHeight int32, views *viewpoint.ViewPointSet, ...) error
- func CheckAdditionalTransactionInputs(tx *btcutil.Tx, txHeight int32, views *viewpoint.ViewPointSet, ...) error
- func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int, timeSource chainutil.MedianTimeSource) error
- func CheckProofOfWork(stubBlock *btcutil.Block, powLimit *big.Int) error
- func CheckTransactionFees(tx *btcutil.Tx, version uint32, storage int64, views *viewpoint.ViewPointSet, ...) (int64, error)
- func CheckTransactionInputs(tx *btcutil.Tx, txHeight int32, views *viewpoint.ViewPointSet, ...) error
- func CheckTransactionIntegrity(tx *btcutil.Tx, views *viewpoint.ViewPointSet, version uint32) error
- func CheckTransactionSanity(tx *btcutil.Tx) error
- func CompactToBig(compact uint32) *big.Int
- func ContractNewStorage(tx *btcutil.Tx, vm *ovm.OVM, paidstoragefees map[[20]byte]int64) int64
- func CountSigOps(tx *btcutil.Tx) int
- func DbFetchHashByHeight(dbTx database.Tx, height int32) (*chainhash.Hash, error)
- func DbFetchHeaderByHash(dbTx database.Tx, hash *chainhash.Hash) (*wire.BlockHeader, error)
- func DbFetchHeightByHash(dbTx database.Tx, hash *chainhash.Hash) (int32, error)
- func DbFetchOrCreateVersion(dbTx database.Tx, key []byte, defaultVersion uint32) (uint32, error)
- func DbFetchVersion(dbTx database.Tx, key []byte) uint32
- func DbPutBlockIndex(dbTx database.Tx, hash *chainhash.Hash, height int32) error
- func DbPutVersion(dbTx database.Tx, key []byte, version uint32) error
- func DbRemoveBlockIndex(dbTx database.Tx, hash *chainhash.Hash, height int32) error
- func DisableLog()
- func GetBlockWeight(blk *btcutil.Block) int64
- func GetSigOpCost(tx *btcutil.Tx, isCoinBaseTx bool, utxoView *viewpoint.UtxoViewpoint, ...) (int, error)
- func GetTransactionWeight(tx *btcutil.Tx) int64
- func HashMerkleBranches(left *chainhash.Hash, right *chainhash.Hash) *chainhash.Hash
- func HashToBig(hash *chainhash.Hash) *big.Int
- func InitBlockNode(node *chainutil.BlockNode, blockHeader *wire.BlockHeader, ...)
- func IsCoinBase(tx *btcutil.Tx) bool
- func IsCoinBaseTx(msgTx *wire.MsgTx) bool
- func IsDbBucketNotFoundErr(err error) bool
- func IsFinalizedTransaction(tx *btcutil.Tx, blockHeight int32, blockTime time.Time) bool
- func IsNotInMainChainErr(err error) bool
- func LockTimeToSequence(isSeconds bool, locktime uint32) uint32
- func MakeMinerSigHash(height int32, hash chainhash.Hash) []byte
- func NewBlockNode(blockHeader *wire.BlockHeader, parent *chainutil.BlockNode) *chainutil.BlockNode
- func SequenceLockActive(sequenceLock *SequenceLock, blockHeight int32, medianTimePast time.Time) bool
- func UseLogger(logger btclog.Logger)
- func ValidateWitnessCommitment(blk *btcutil.Block) error
- type AssertError
- type BehaviorFlags
- type BestState
- type BlockChain
- func (b *BlockChain) Advance(x *list.Element) int32
- func (b *BlockChain) Ancestor(blockNode *chainutil.BlockNode, blockHeight int32) *chainutil.BlockNode
- func (b *BlockChain) AnyBlockByHash(hash *chainhash.Hash) (*btcutil.Block, error)
- func (b *BlockChain) BestChainContains(hash *chainhash.Hash) bool
- func (b *BlockChain) BestSnapshot() *BestState
- func (b *BlockChain) BlockByHash(hash *chainhash.Hash) (*btcutil.Block, error)
- func (b *BlockChain) BlockByHeight(blockHeight int32) (*btcutil.Block, error)
- func (b *BlockChain) BlockHashByHeight(blockHeight int32) (*chainhash.Hash, error)
- func (b *BlockChain) BlockHeightByHash(hash *chainhash.Hash) (int32, error)
- func (b *BlockChain) BlockLocatorFromHash(hash *chainhash.Hash) chainhash.BlockLocator
- func (b *BlockChain) CalcSequenceLock(tx *btcutil.Tx, utxoView *viewpoint.UtxoViewpoint, mempool bool) (*SequenceLock, error)
- func (b *BlockChain) CancelNotification(index int)
- func (b *BlockChain) Canvas(block *btcutil.Block) (*viewpoint.ViewPointSet, *ovm.OVM)
- func (b *BlockChain) CheckCollateral(block *wire.MinerBlock, latest *chainhash.Hash, flags BehaviorFlags) (uint32, error)
- func (b *BlockChain) CheckConnectBlockTemplate(block *btcutil.Block) error
- func (b *BlockChain) CheckForfeit(block *btcutil.Block, prevNode *chainutil.BlockNode, ...) error
- func (b *BlockChain) CheckProofOfWork(block *btcutil.Block, powLimit *big.Int) error
- func (b *BlockChain) CheckSideChain(hash *chainhash.Hash)
- func (b *BlockChain) Checkpoints() []chaincfg.Checkpoint
- func (g *BlockChain) CompTxs(prevNode *chainutil.BlockNode, views *viewpoint.ViewPointSet) ([]*wire.MsgTx, error)
- func (b *BlockChain) FastReorganizeChain(attachNodes *list.List) error
- func (b *BlockChain) FetchBorderEntry(hash chainhash.Hash) (*viewpoint.BorderEntry, error)
- func (b *BlockChain) FetchPolygonEntry(hash chainhash.Hash) (*viewpoint.PolygonEntry, error)
- func (b *BlockChain) FetchRightEntry(hash chainhash.Hash) (*viewpoint.RightEntry, error)
- func (b *BlockChain) FetchRightSetEntry(hash chainhash.Hash) (*viewpoint.RightSetEntry, error)
- func (b *BlockChain) FetchSpendJournal(targetBlock *btcutil.Block) ([]viewpoint.SpentTxOut, error)
- func (b *BlockChain) FetchUtxoEntry(outpoint wire.OutPoint) (*viewpoint.UtxoEntry, error)
- func (b *BlockChain) FetchUtxoView(tx *btcutil.Tx) (*viewpoint.ViewPointSet, error)
- func (b *BlockChain) FindFork(node *chainutil.BlockNode) *chainutil.BlockNode
- func (b *BlockChain) GetAccounts() map[[21]byte]int64
- func (b *BlockChain) GetMinerTPS(miner [20]byte) *TPHRecord
- func (b *BlockChain) GetReorganizeSideChain(hash chainhash.Hash) (*list.List, *list.List)
- func (b *BlockChain) HasCheckpoints() bool
- func (b *BlockChain) HashToBlock(hash *chainhash.Hash) (*btcutil.Block, error)
- func (b *BlockChain) HaveBlock(hash *chainhash.Hash) (bool, error)
- func (b *BlockChain) HaveNode(h *chainhash.Hash) bool
- func (b *BlockChain) HeaderByHash(hash *chainhash.Hash) (wire.BlockHeader, error)
- func (b *BlockChain) HeightRange(startHeight, endHeight int32) ([]chainhash.Hash, error)
- func (b *BlockChain) HeightToHashRange(startHeight int32, endHash *chainhash.Hash, maxResults int) ([]chainhash.Hash, error)
- func (b *BlockChain) InBestChain(u *chainhash.Hash) bool
- func (b *BlockChain) InitCollateral()
- func (b *BlockChain) IntervalBlockHashes(endHash *chainhash.Hash, interval int) ([]chainhash.Hash, error)
- func (b *BlockChain) IsCheckpointCandidate(block *btcutil.Block) (bool, error)
- func (b *BlockChain) IsCurrent() bool
- func (b *BlockChain) LatestBlockLocator() (chainhash.BlockLocator, error)
- func (b *BlockChain) LatestCheckpoint() *chaincfg.Checkpoint
- func (b *BlockChain) LocateBlocks(locator chainhash.BlockLocator, hashStop *chainhash.Hash, maxHashes uint32) []chainhash.Hash
- func (b *BlockChain) LocateHeaders(locator chainhash.BlockLocator, hashStop *chainhash.Hash) []wire.BlockHeader
- func (b *BlockChain) LongestTip() *chainutil.BlockNode
- func (b *BlockChain) MainChainHasBlock(hash *chainhash.Hash) bool
- func (b *BlockChain) MainChainNodeByHash(h *chainhash.Hash) *chainutil.BlockNode
- func (b *BlockChain) MainChainTx(txHash chainhash.Hash) *wire.MsgTx
- func (b *BlockChain) MaxContractExec(lastBlk chainhash.Hash, cbest chainhash.Hash) int64
- func (b *BlockChain) NewViewPointSet() *viewpoint.ViewPointSet
- func (b *BlockChain) NodeByHash(h *chainhash.Hash) *chainutil.BlockNode
- func (b *BlockChain) NodeByHeight(blockHeight int32) *chainutil.BlockNode
- func (b *BlockChain) NodetoHeader(node *chainutil.BlockNode) wire.BlockHeader
- func (b *BlockChain) OnNewMinerNode()
- func (b *BlockChain) ParentNode(n *chainutil.BlockNode) *chainutil.BlockNode
- func (b *BlockChain) PrepForfeit(prevNode *chainutil.BlockNode) ([]reportedblk, int32, error)
- func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bool, bool, error, int32, *chainhash.Hash)
- func (b *BlockChain) ProcessOrphans(hash *chainhash.Hash, flags BehaviorFlags) error
- func (b *BlockChain) Rebuildutxo(index indexer)
- func (b *BlockChain) ReorganizeChain(detachNodes, attachNodes *list.List) error
- func (b *BlockChain) Rotation(hash chainhash.Hash) int32
- func (b *BlockChain) SameChain(u, w chainhash.Hash) bool
- func (b *BlockChain) SendNotification(typ NotificationType, data interface{})
- func (b *BlockChain) SideChainContains(x *list.Element, hash chainhash.Hash) bool
- func (b *BlockChain) SignedBy(x *list.Element, miners []*[20]byte) bool
- func (b *BlockChain) Subscribe(callback NotificationCallback) int
- func (b *BlockChain) TotalRotate(lst *list.List) int32
- func (b *BlockChain) TphNotice(t *Notification)
- func (b *BlockChain) TryConnectOrphan(hash *chainhash.Hash) bool
- func (b *BlockChain) TxInMainChain(txHash *chainhash.Hash, height int32) bool
- type Config
- type DeploymentError
- type ErrorCode
- type IndexManager
- type MinerChain
- type Notification
- type NotificationCallback
- type NotificationType
- type RuleError
- type SequenceLock
- type TPHRecord
- type TPSrv
- type TphPocket
Examples ¶
Constants ¶
const ( // CoinbaseWitnessDataLen is the required length of the only element within // the coinbase's witness data if the coinbase transaction contains a // witness commitment. CoinbaseWitnessDataLen = 32 // CoinbaseWitnessPkScriptLength is the length of the public key script // containing an OP_RETURN, the WitnessMagicBytes, and the witness // commitment itself. In order to be a valid candidate for the output // containing the witness commitment CoinbaseWitnessPkScriptLength = 38 )
const CONTRACTTXRATIO = 30 // when calculating TPS, every 30 contract exec steps = 1 sig
const CheckpointConfirmations = 2016
CheckpointConfirmations is the number of blocks before the end of the current best block chain that a good checkpoint candidate must be.
const ( // LockTimeThreshold is the number below which a lock time is // interpreted to be a block number. LockTimeThreshold = 0x5effa4cf // genesis time )
const ( // MaxTimeOffsetSeconds is the maximum number of seconds a block time // is allowed to be ahead of the current time. This is currently 2 // hours. MaxTimeOffsetSeconds = 2 * 60 * 60 )
const ( // time (blocks) to hold miner account MinerHoldingPeriod = 3 * wire.MINER_RORATE_FREQ )
Variables ¶
var ( // IssuedTokenTypes is the name of the db bucket used to house the map // from token type to contract. IssuedTokenTypes = []byte("issuedTokens") // UtxoSetBucketName is the name of the db bucket used to house the // unspent transaction output set. UtxoSetBucketName = []byte("utxosetv2") )
Functions ¶
func BigToCompact ¶
BigToCompact converts a whole number N to a compact representation using an unsigned 32-bit number. The compact representation only provides 23 bits of precision, so values larger than (2^23 - 1) only encode the most significant digits of the number. See CompactToBig for details.
Example ¶
This example demonstrates how to convert a target difficulty into the compact "bits" in a block header which represent that target difficulty .
package main import ( "fmt" "math/big" "github.com/zeusyf/btcd/blockchain" _ "github.com/zeusyf/btcd/database/ffldb" ) func main() { // Convert the target difficulty from block 300000 in the main block // chain to compact form. t := "0000000000000000896c00000000000000000000000000000000000000000000" targetDifficulty, success := new(big.Int).SetString(t, 16) if !success { fmt.Println("invalid target difficulty") return } bits := blockchain.BigToCompact(targetDifficulty) fmt.Println(bits) }
Output: 419465580
func BlockIndexKey ¶
BlockIndexKey generates the binary key for an entry in the block index bucket. The key is composed of the block height encoded as a big-endian 32-bit unsigned int followed by the 32 byte block hash.
func BuildMerkleTreeStore ¶
func BuildMerkleTreeStore(transactions []*btcutil.Tx, witness bool, version uint32) []*chainhash.Hash
BuildMerkleTreeStore creates a merkle tree from a slice of transactions, stores it using a linear array, and returns a slice of the backing array. A linear array was chosen as opposed to an actual tree structure since it uses about half as much memory. The following describes a merkle tree and how it is stored in a linear array.
A merkle tree is a tree in which every non-leaf node is the hash of its children nodes. A diagram depicting how this works for bitcoin transactions where h(x) is a double sha256 follows:
root = h1234 = h(h12 + h34) / \ h12 = h(h1 + h2) h34 = h(h3 + h4) / \ / \ h1 = h(tx1) h2 = h(tx2) h3 = h(tx3) h4 = h(tx4)
The above stored as a linear array is as follows:
[h1 h2 h3 h4 h12 h34 root]
As the above shows, the merkle root is always the last element in the array.
The number of inputs is not always a power of two which results in a balanced tree structure as above. In that case, parent nodes with no children are also zero and parent nodes with only a single left node are calculated by concatenating the left node with itself before hashing. Since this function uses nodes that are pointers to the hashes, empty nodes will be nil.
The additional bool parameter indicates if we are generating the merkle tree using witness transaction id's rather than regular transaction id's. This also presents an additional case wherein the wtxid of the coinbase transaction is the zeroHash.
func CalcBlockSubsidy ¶
CalcBlockSubsidy returns the subsidy amount a block at the provided height should have. This is mainly used for determining how much the coinbase for newly generated blocks awards as well as validating the coinbase for blocks has the expected value.
The subsidy is halved every SubsidyReductionInterval blocks. Mathematically this is: baseSubsidy / 2^(height/SubsidyReductionInterval)
At the target block generation rate for the main network, this is approximately every 4 years.
func CalcWork ¶
CalcWork calculates a work value from difficulty bits. Bitcoin increases the difficulty for generating a block by decreasing the value which the generated hash must be less than. This difficulty target is stored in each block header using a compact representation as described in the documentation for CompactToBig. The main chain is selected by choosing the chain that has the most proof of work (highest difficulty). Since a lower target difficulty value equates to higher actual difficulty, the work value which will be accumulated must be the inverse of the difficulty. Also, in order to avoid potential division by zero and really small floating point numbers, the result adds 1 to the denominator and multiplies the numerator by 2^256.
func CheckBlockSanity ¶
func CheckBlockSanity(block *btcutil.Block, powLimit *big.Int, timeSource chainutil.MedianTimeSource) error
CheckBlockSanity performs some preliminary checks on a block to ensure it is sane before continuing with block processing. These checks are context free.
func CheckTransactionFees ¶
func CheckTransactionInputs ¶
func CheckTransactionInputs(tx *btcutil.Tx, txHeight int32, views *viewpoint.ViewPointSet, chainParams *chaincfg.Params) error
CheckTransactionInputs performs a series of checks on the inputs to a transaction to ensure they are valid. An example of some of the checks include verifying all inputs exist, ensuring the coinbase seasoning requirements are met, detecting double spends, validating all values and fees are in the legal range and the total output amount doesn't exceed the input amount, and verifying the signatures to prove the spender was the owner of the bitcoins and therefore allowed to spend them. As it checks the inputs, it also calculates the total fees for the transaction and returns that value.
NOTE: The transaction MUST have already been sanity checked with the CheckTransactionSanity function prior to calling this function.
func CheckTransactionSanity ¶
CheckTransactionSanity performs some preliminary checks on a transaction to ensure it is sane. These checks are context free.
func CompactToBig ¶
CompactToBig converts a compact representation of a whole number N to an unsigned 32-bit number. The representation is similar to IEEE754 floating point numbers.
Like IEEE754 floating point, there are three basic components: the sign, the exponent, and the mantissa. They are broken out as follows:
the most significant 8 bits represent the unsigned base 256 exponent
bit 23 (the 24th bit) represents the sign bit
the least significant 23 bits represent the mantissa
------------------------------------------------- | Exponent | Sign | Mantissa | ------------------------------------------------- | 8 bits [31-24] | 1 bit [23] | 23 bits [22-00] | -------------------------------------------------
The formula to calculate N is:
N = (-1^sign) * mantissa * 256^(exponent-3)
This compact form is only used in bitcoin to encode unsigned 256-bit numbers which represent difficulty targets, thus there really is not a need for a sign bit, but it is implemented here to stay consistent with bitcoind.
Example ¶
This example demonstrates how to convert the compact "bits" in a block header which represent the target difficulty to a big integer and display it using the typical hex notation.
package main import ( "fmt" "github.com/zeusyf/btcd/blockchain" _ "github.com/zeusyf/btcd/database/ffldb" ) func main() { // Convert the bits from block 300000 in the main block chain. bits := uint32(419465580) targetDifficulty := blockchain.CompactToBig(bits) // Display it in hex. fmt.Printf("%064x\n", targetDifficulty.Bytes()) }
Output: 0000000000000000896c00000000000000000000000000000000000000000000
func ContractNewStorage ¶
func CountSigOps ¶
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 txscript.
func DbFetchHashByHeight ¶
DbFetchHashByHeight uses an existing database transaction to retrieve the hash for the provided height from the index.
func DbFetchHeaderByHash ¶
DbFetchHeaderByHash uses an existing database transaction to retrieve the block header for the provided hash.
func DbFetchHeightByHash ¶
DbFetchHeightByHash uses an existing database transaction to retrieve the height for the provided hash from the index.
func DbFetchOrCreateVersion ¶
dbFetchOrCreateVersion uses an existing database transaction to attempt to fetch the provided key from the metadata bucket as a version and in the case it doesn't exist, it adds the entry with the provided default version and returns that. This is useful during upgrades to automatically handle loading and adding version keys as necessary.
func DbFetchVersion ¶
DbFetchVersion fetches an individual version with the given key from the metadata bucket. It is primarily used to track versions on entities such as buckets. It returns zero if the provided key does not exist.
func DbPutBlockIndex ¶
DbPutBlockIndex uses an existing database transaction to update or add the block index entries for the hash to height and height to hash mappings for the provided values.
func DbPutVersion ¶
DbPutVersion uses an existing database transaction to update the provided key in the metadata bucket to the given version. It is primarily used to track versions on entities such as buckets.
func DbRemoveBlockIndex ¶
DbRemoveBlockIndex uses an existing database transaction remove block index entries from the hash to height and height to hash mappings for the provided values.
func DisableLog ¶
func DisableLog()
DisableLog disables all library log output. Logging output is disabled by default until UseLogger is called.
func GetBlockWeight ¶
GetBlockWeight computes the value of the weight metric for a given block. Currently the weight metric is simply the sum of the block's serialized size without any witness data scaled proportionally by the WitnessScaleFactor, and the block's serialized size including any witness data.
func GetSigOpCost ¶
func GetSigOpCost(tx *btcutil.Tx, isCoinBaseTx bool, utxoView *viewpoint.UtxoViewpoint, bip16, segWit bool) (int, error)
GetSigOpCost returns the unified sig op cost for the passed transaction respecting current active soft-forks which modified sig op cost counting. The unified sig op cost for a transaction is computed as the sum of: the legacy sig op count scaled according to the WitnessScaleFactor, the sig op count for all p2sh inputs scaled by the WitnessScaleFactor, and finally the unscaled sig op count for any inputs spending witness programs.
func GetTransactionWeight ¶
GetTransactionWeight computes the value of the weight metric for a given transaction. Currently the weight metric is simply the sum of the transactions's serialized size without any witness data scaled proportionally by the WitnessScaleFactor, and the transaction's serialized size including any witness data.
func HashMerkleBranches ¶
HashMerkleBranches takes two hashes, treated as the left and right tree nodes, and returns the hash of their concatenation. This is a helper function used to aid in the generation of a merkle tree.
func HashToBig ¶
HashToBig converts a chainhash.Hash into a big.Int that can be used to perform math comparisons.
func InitBlockNode ¶
func InitBlockNode(node *chainutil.BlockNode, blockHeader *wire.BlockHeader, parent *chainutil.BlockNode)
InitBlockNode initializes a block node from the given header and parent node, calculating the Height and workSum from the respective fields on the parent. This function is NOT safe for concurrent access. It must only be called when initially creating a node.
func IsCoinBase ¶
IsCoinBase determines whether or not a transaction is a coinbase. A coinbase is a special transaction created by miners that has no inputs. This is represented in the block chain by a transaction with a single input that has a previous output transaction index set to the maximum value along with a zero hash.
This function only differs from IsCoinBaseTx in that it works with a higher level util transaction as opposed to a raw wire transaction.
func IsCoinBaseTx ¶
IsCoinBaseTx determines whether or not a transaction is a coinbase. A coinbase is a special transaction created by miners that has no inputs. This is represented in the block chain by a transaction with a single input that has a previous output transaction index set to the maximum value along with a zero hash.
This function only differs from IsCoinBase in that it works with a raw wire transaction as opposed to a higher level util transaction.
func IsDbBucketNotFoundErr ¶
isDbBucketNotFoundErr returns whether or not the passed error is a database.Error with an error code of database.ErrBucketNotFound.
func IsFinalizedTransaction ¶
IsFinalizedTransaction determines whether or not a transaction is finalized.
func IsNotInMainChainErr ¶
IsNotInMainChainErr returns whether or not the passed error is an errNotInMainChain error.
func LockTimeToSequence ¶
LockTimeToSequence converts the passed relative locktime to a sequence number in accordance to BIP-68. See: https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
- (Compatibility)
func NewBlockNode ¶
newBlockNode returns a new block node for the given block header and parent node, calculating the Height and workSum from the respective fields on the parent. This function is NOT safe for concurrent access.
func SequenceLockActive ¶
func SequenceLockActive(sequenceLock *SequenceLock, blockHeight int32, medianTimePast time.Time) bool
SequenceLockActive determines if a transaction's sequence locks have been met, meaning that all the inputs of a given transaction have reached a height or time sufficient for their relative lock-time maturity.
func ValidateWitnessCommitment ¶
ValidateWitnessCommitment validates the witness commitment (if any) found within the coinbase transaction of the passed block.
Types ¶
type AssertError ¶
type AssertError string
AssertError identifies an error that indicates an internal code consistency issue and should be treated as a critical and unrecoverable error.
func (AssertError) Error ¶
func (e AssertError) Error() string
Error returns the assertion error as a human-readable string and satisfies the error interface.
type BehaviorFlags ¶
type BehaviorFlags uint32
BehaviorFlags is a bitmask defining tweaks to the normal behavior when performing chain processing and consensus rules checks.
const ( // BFFastAdd may be set to indicate that several checks can be avoided // for the block since it is already known to fit into the chain due to // already proving it correct links into the chain up to a known // 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 BFAddAsOrphan BFSubmission BFNoConnect BFNoReorg BFSideChain BFWatingFactor BFAlreadyInChain BFEasyBlocks // BFNone is a convenience value to specifically indicate no flags. BFNone BehaviorFlags = 0 )
type BestState ¶
type BestState struct { Hash chainhash.Hash // The hash of the block. Height int32 // The height of the block. Bits uint32 // The difficulty bits of the block. TotalTxns uint64 // The total number of txns in the chain. MedianTime time.Time // Median time as per CalcPastMedianTime. LastRotation uint32 // height of the last rotate in Miner. normally // values below are not store in DB BlockSize uint64 // The size of the best block. NumTxns uint64 // The number of txns in the block. Updated time.Time // local time the best state was updated. }
BestState houses information about the current best block and other info related to the state of the main chain as it exists from the point of view of the current best block.
The BestSnapshot method can be used to obtain access to this information in a concurrent safe manner and the data will not be changed out from under the caller when chain state changes occur as the function name implies. However, the returned snapshot must be treated as immutable since it is shared by all callers.
type BlockChain ¶
type BlockChain struct { ChainParams *chaincfg.Params Miners MinerChain // The Miner chain to provide the next Miner // ChainLock protects concurrent access to the vast majority of the // fields in this struct below this point. ChainLock sync.RWMutex BestChain *chainutil.ChainView // These fields are related to handling of orphan blocks. They are // protected by a combination of the chain lock and the orphan lock. Orphans *chainutil.Orphans // The state is used as a fairly efficient way to cache information // about the current best chain state that is returned to callers when // requested. It operates on the principle of MVCC such that any time a // new block becomes the best block, the state pointer is replaced with // a new struct and the old state is left untouched. In this way, // multiple callers can be pointing to different best chain states. // This is acceptable for most callers because the state is only being // queried at a specific point in time. // // In addition, some of the fields are stored in the database so the // chain state can be quickly reconstructed on load. StateLock sync.RWMutex Miner []btcutil.Address PrivKey []*btcec.PrivateKey // records about miner's performance MinerTPH map[[20]byte]*TPHRecord LockedCollaterals map[wire.OutPoint]struct{} // reference counts of them // running consensus in this range ConsensusRange [2]int32 // are we packing tx blocks? IsPacking bool // address usage index. use in forfeiture AddrUsage func(address btcutil.Address) uint32 // tmp data BTfile *os.File // contains filtered or unexported fields }
BlockChain provides functions for working with the bitcoin block chain. It includes functionality such as rejecting duplicate blocks, ensuring blocks follow all rules, orphan handling, checkpoint handling, and best chain selection with reorganization.
func New ¶
func New(config *Config) (*BlockChain, error)
New returns a BlockChain instance using the provided configuration details.
func (*BlockChain) AnyBlockByHash ¶
func (*BlockChain) BestChainContains ¶
func (b *BlockChain) BestChainContains(hash *chainhash.Hash) bool
func (*BlockChain) BestSnapshot ¶
func (b *BlockChain) BestSnapshot() *BestState
BestSnapshot returns information about the current best chain block and related state as of the current point in time. The returned instance must be treated as immutable since it is shared by all callers.
This function is safe for concurrent access.
func (*BlockChain) BlockByHash ¶
BlockByHash returns the block from the main chain with the given hash with the appropriate chain height set.
This function is safe for concurrent access.
func (*BlockChain) BlockByHeight ¶
func (b *BlockChain) BlockByHeight(blockHeight int32) (*btcutil.Block, error)
BlockByHeight returns the block at the given height in the main chain.
This function is safe for concurrent access.
func (*BlockChain) BlockHashByHeight ¶
func (b *BlockChain) BlockHashByHeight(blockHeight int32) (*chainhash.Hash, error)
BlockHashByHeight returns the hash of the block at the given height in the main chain.
This function is safe for concurrent access.
func (*BlockChain) BlockHeightByHash ¶
func (b *BlockChain) BlockHeightByHash(hash *chainhash.Hash) (int32, error)
BlockHeightByHash returns the height of the block with the given hash in the main chain.
This function is safe for concurrent access.
func (*BlockChain) BlockLocatorFromHash ¶
func (b *BlockChain) BlockLocatorFromHash(hash *chainhash.Hash) chainhash.BlockLocator
BlockLocatorFromHash returns a block locator for the passed block hash. See BlockLocator for details on the algorithm used to create a block locator.
In addition to the general algorithm referenced above, this function will return the block locator for the latest known tip of the main (best) chain if the passed hash is not currently known.
This function is safe for concurrent access.
func (*BlockChain) CalcSequenceLock ¶
func (b *BlockChain) CalcSequenceLock(tx *btcutil.Tx, utxoView *viewpoint.UtxoViewpoint, mempool bool) (*SequenceLock, error)
CalcSequenceLock computes a relative lock-time SequenceLock for the passed transaction using the passed UtxoViewpoint to obtain the past median time for blocks in which the referenced inputs of the transactions were included within. The generated SequenceLock lock can be used in conjunction with a block height, and adjusted median block time to determine if all the inputs referenced within a transaction have reached sufficient maturity allowing the candidate transaction to be included in a block.
This function is safe for concurrent access.
func (*BlockChain) CancelNotification ¶
func (b *BlockChain) CancelNotification(index int)
CancelNotification cancels a notification.
func (*BlockChain) Canvas ¶
func (b *BlockChain) Canvas(block *btcutil.Block) (*viewpoint.ViewPointSet, *ovm.OVM)
func (*BlockChain) CheckCollateral ¶
func (b *BlockChain) CheckCollateral(block *wire.MinerBlock, latest *chainhash.Hash, flags BehaviorFlags) (uint32, error)
checkBlockSanity check whether the miner has provided sufficient collateral
func (*BlockChain) CheckConnectBlockTemplate ¶
func (b *BlockChain) CheckConnectBlockTemplate(block *btcutil.Block) error
CheckConnectBlockTemplate fully validates that connecting the passed block to the main chain does not violate any consensus rules, aside from the proof of work requirement. The block must connect to the current tip of the main chain.
This function is safe for concurrent access.
func (*BlockChain) CheckForfeit ¶
func (b *BlockChain) CheckForfeit(block *btcutil.Block, prevNode *chainutil.BlockNode, views *viewpoint.ViewPointSet) error
func (*BlockChain) CheckProofOfWork ¶
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 (*BlockChain) CheckSideChain ¶
func (b *BlockChain) CheckSideChain(hash *chainhash.Hash)
func (*BlockChain) Checkpoints ¶
func (b *BlockChain) Checkpoints() []chaincfg.Checkpoint
Checkpoints returns a slice of checkpoints (regardless of whether they are already known). When there are no checkpoints for the chain, it will return nil.
This function is safe for concurrent access.
func (*BlockChain) CompTxs ¶
func (g *BlockChain) CompTxs(prevNode *chainutil.BlockNode, views *viewpoint.ViewPointSet) ([]*wire.MsgTx, error)
CompTxs is the main function to genrate compensation transactions.
func (*BlockChain) FastReorganizeChain ¶
func (b *BlockChain) FastReorganizeChain(attachNodes *list.List) error
func (*BlockChain) FetchBorderEntry ¶
func (b *BlockChain) FetchBorderEntry(hash chainhash.Hash) (*viewpoint.BorderEntry, error)
FetchVtxEntry loads and returns the requested vertex definition from the point of view of the end of the main chain.
NOTE: Requesting an definition for which there is no data will NOT return an error. Instead both the entry and the error will be nil. In practice this means the caller must check if the returned entry is nil before invoking methods on it.
This function is safe for concurrent access however the returned entry (if any) is NOT.
func (*BlockChain) FetchPolygonEntry ¶
func (b *BlockChain) FetchPolygonEntry(hash chainhash.Hash) (*viewpoint.PolygonEntry, error)
FetchVtxEntry loads and returns the requested vertex definition from the point of view of the end of the main chain.
NOTE: Requesting an definition for which there is no data will NOT return an error. Instead both the entry and the error will be nil. In practice this means the caller must check if the returned entry is nil before invoking methods on it.
This function is safe for concurrent access however the returned entry (if any) is NOT.
func (*BlockChain) FetchRightEntry ¶
func (b *BlockChain) FetchRightEntry(hash chainhash.Hash) (*viewpoint.RightEntry, error)
FetchVtxEntry loads and returns the requested vertex definition from the point of view of the end of the main chain.
NOTE: Requesting an definition for which there is no data will NOT return an error. Instead both the entry and the error will be nil. In practice this means the caller must check if the returned entry is nil before invoking methods on it.
This function is safe for concurrent access however the returned entry (if any) is NOT.
func (*BlockChain) FetchRightSetEntry ¶
func (b *BlockChain) FetchRightSetEntry(hash chainhash.Hash) (*viewpoint.RightSetEntry, error)
func (*BlockChain) FetchSpendJournal ¶
func (b *BlockChain) FetchSpendJournal(targetBlock *btcutil.Block) ([]viewpoint.SpentTxOut, error)
FetchSpendJournal attempts to retrieve the spend journal, or the set of outputs spent for the target block. This provides a view of all the outputs that will be consumed once the target block is connected to the end of the main chain.
This function is safe for concurrent access.
func (*BlockChain) FetchUtxoEntry ¶
FetchUtxoEntry loads and returns the requested unspent transaction output from the point of view of the end of the main chain.
NOTE: Requesting an output for which there is no data will NOT return an error. Instead both the entry and the error will be nil. This is done to allow pruning of spent transaction outputs. In practice this means the caller must check if the returned entry is nil before invoking methods on it.
This function is safe for concurrent access however the returned entry (if any) is NOT.
func (*BlockChain) FetchUtxoView ¶
func (b *BlockChain) FetchUtxoView(tx *btcutil.Tx) (*viewpoint.ViewPointSet, error)
FetchUtxoView loads unspent transaction outputs for the inputs referenced by the passed transaction from the point of view of the end of the main chain. It also attempts to fetch the utxos for the outputs of the transaction itself so the returned view can be examined for duplicate transactions.
This function is safe for concurrent access however the returned view is NOT.
func (*BlockChain) FindFork ¶
func (b *BlockChain) FindFork(node *chainutil.BlockNode) *chainutil.BlockNode
findFork returns the final common block between the provided node and the the chain view. It will return nil if there is no common block. This only differs from the exported Version in that it is up to the caller to ensure the lock is held.
See the exported FindFork comments for more details.
This function MUST be called with the view mutex locked (for reads).
func (*BlockChain) GetAccounts ¶
func (b *BlockChain) GetAccounts() map[[21]byte]int64
func (*BlockChain) GetMinerTPS ¶
func (b *BlockChain) GetMinerTPS(miner [20]byte) *TPHRecord
func (*BlockChain) GetReorganizeSideChain ¶
func (*BlockChain) HasCheckpoints ¶
func (b *BlockChain) HasCheckpoints() bool
HasCheckpoints returns whether this BlockChain has checkpoints defined.
This function is safe for concurrent access.
func (*BlockChain) HashToBlock ¶
func (*BlockChain) HaveBlock ¶
func (b *BlockChain) HaveBlock(hash *chainhash.Hash) (bool, error)
HaveBlock returns whether or not the chain instance has the block represented by the passed hash. This includes checking the various places a block can be like part of the main chain, on a side chain, or in the orphan pool.
This function is safe for concurrent access.
func (*BlockChain) HeaderByHash ¶
func (b *BlockChain) HeaderByHash(hash *chainhash.Hash) (wire.BlockHeader, error)
HeaderByHash returns the block header identified by the given hash or an error if it doesn't exist. Note that this will return headers from both the main and side chains.
func (*BlockChain) HeightRange ¶
func (b *BlockChain) HeightRange(startHeight, endHeight int32) ([]chainhash.Hash, error)
HeightRange returns a range of block hashes for the given start and end heights. It is inclusive of the start height and exclusive of the end height. The end height will be limited to the current main chain height.
This function is safe for concurrent access.
func (*BlockChain) HeightToHashRange ¶
func (b *BlockChain) HeightToHashRange(startHeight int32, endHash *chainhash.Hash, maxResults int) ([]chainhash.Hash, error)
HeightToHashRange returns a range of block hashes for the given start height and end hash, inclusive on both ends. The hashes are for all blocks that are ancestors of endHash with height greater than or equal to startHeight. The end hash must belong to a block that is known to be valid.
This function is safe for concurrent access.
func (*BlockChain) InBestChain ¶
func (b *BlockChain) InBestChain(u *chainhash.Hash) bool
func (*BlockChain) InitCollateral ¶
func (b *BlockChain) InitCollateral()
func (*BlockChain) IntervalBlockHashes ¶
func (b *BlockChain) IntervalBlockHashes(endHash *chainhash.Hash, interval int, ) ([]chainhash.Hash, error)
IntervalBlockHashes returns hashes for all blocks that are ancestors of endHash where the block height is a positive multiple of interval.
This function is safe for concurrent access.
func (*BlockChain) IsCheckpointCandidate ¶
func (b *BlockChain) IsCheckpointCandidate(block *btcutil.Block) (bool, error)
IsCheckpointCandidate returns whether or not the passed block is a good checkpoint candidate.
The factors used to determine a good checkpoint are:
- The block must be in the main chain
- The block must be at least 'CheckpointConfirmations' blocks prior to the current end of the main chain
- The timestamps for the blocks before and after the checkpoint must have timestamps which are also before and after the checkpoint, respectively (due to the median time allowance this is not always the case)
- The block must not contain any strange transaction such as those with nonstandard scripts
The intent is that candidates are reviewed by a developer to make the final decision and then manually added to the list of checkpoints for a network.
This function is safe for concurrent access.
func (*BlockChain) IsCurrent ¶
func (b *BlockChain) IsCurrent() bool
IsCurrent returns whether or not the chain believes it is current. Several factors are used to guess, but the key factors that allow the chain to believe it is current are:
- Latest block height is after the latest checkpoint (if enabled)
- Latest block has a timestamp newer than 24 hours ago
This function is safe for concurrent access.
func (*BlockChain) LatestBlockLocator ¶
func (b *BlockChain) LatestBlockLocator() (chainhash.BlockLocator, error)
LatestBlockLocator returns a block locator for the latest known tip of the main (best) chain.
This function is safe for concurrent access.
func (*BlockChain) LatestCheckpoint ¶
func (b *BlockChain) LatestCheckpoint() *chaincfg.Checkpoint
LatestCheckpoint returns the most recent checkpoint (regardless of whether it is already known). When there are no defined checkpoints for the active chain instance, it will return nil.
This function is safe for concurrent access.
func (*BlockChain) LocateBlocks ¶
func (b *BlockChain) LocateBlocks(locator chainhash.BlockLocator, hashStop *chainhash.Hash, maxHashes uint32) []chainhash.Hash
LocateBlocks returns the hashes of the blocks after the first known block in the locator until the provided stop hash is reached, or up to the provided max number of block hashes.
In addition, there are two special cases:
- When no locators are provided, the stop hash is treated as a request for that block, so it will either return the stop hash itself if it is known, or nil if it is unknown
- When locators are provided, but none of them are known, hashes starting after the genesis block will be returned
This function is safe for concurrent access.
func (*BlockChain) LocateHeaders ¶
func (b *BlockChain) LocateHeaders(locator chainhash.BlockLocator, hashStop *chainhash.Hash) []wire.BlockHeader
LocateHeaders returns the headers of the blocks after the first known block in the locator until the provided stop hash is reached, or up to a max of wire.MaxBlockHeadersPerMsg headers.
In addition, there are two special cases:
- When no locators are provided, the stop hash is treated as a request for that header, so it will either return the header for the stop hash itself if it is known, or nil if it is unknown
- When locators are provided, but none of them are known, headers starting after the genesis block will be returned
This function is safe for concurrent access.
func (*BlockChain) LongestTip ¶
func (b *BlockChain) LongestTip() *chainutil.BlockNode
func (*BlockChain) MainChainHasBlock ¶
func (b *BlockChain) MainChainHasBlock(hash *chainhash.Hash) bool
MainChainHasBlock returns whether or not the block with the given hash is in the main chain.
This function is safe for concurrent access.
func (*BlockChain) MainChainNodeByHash ¶
func (b *BlockChain) MainChainNodeByHash(h *chainhash.Hash) *chainutil.BlockNode
func (*BlockChain) MainChainTx ¶
func (b *BlockChain) MainChainTx(txHash chainhash.Hash) *wire.MsgTx
func (*BlockChain) MaxContractExec ¶
func (*BlockChain) NewViewPointSet ¶
func (b *BlockChain) NewViewPointSet() *viewpoint.ViewPointSet
func (*BlockChain) NodeByHash ¶
func (b *BlockChain) NodeByHash(h *chainhash.Hash) *chainutil.BlockNode
func (*BlockChain) NodeByHeight ¶
func (b *BlockChain) NodeByHeight(blockHeight int32) *chainutil.BlockNode
func (*BlockChain) NodetoHeader ¶
func (b *BlockChain) NodetoHeader(node *chainutil.BlockNode) wire.BlockHeader
Header constructs a block header from the node and returns it.
This function is safe for concurrent access.
func (*BlockChain) OnNewMinerNode ¶
func (b *BlockChain) OnNewMinerNode()
func (*BlockChain) ParentNode ¶
func (b *BlockChain) ParentNode(n *chainutil.BlockNode) *chainutil.BlockNode
func (*BlockChain) PrepForfeit ¶
func (b *BlockChain) PrepForfeit(prevNode *chainutil.BlockNode) ([]reportedblk, int32, error)
perpare to make compensation for double signing victims this function returns side chain violating blocks that should be compensated in the block after prevNode for each violating miner (upto 2).
func (*BlockChain) ProcessBlock ¶
func (b *BlockChain) ProcessBlock(block *btcutil.Block, flags BehaviorFlags) (bool, bool, error, int32, *chainhash.Hash)
ProcessBlock is the main workhorse for handling insertion of new blocks into the block chain. It includes functionality such as rejecting duplicate blocks, ensuring blocks follow all rules, orphan handling, and insertion into the block chain along with best chain selection and reorganization.
When no errors occurred during processing, the first return value indicates whether or not the block is on the main chain and the second indicates whether or not the block is an orphan.
This function is safe for concurrent access.
Example ¶
This example demonstrates how to create a new chain instance and use ProcessBlock to attempt to add a block to the chain. As the package overview documentation describes, this includes all of the Bitcoin consensus rules. This example intentionally attempts to insert a duplicate genesis block to illustrate how an invalid block is handled.
package main import ( "fmt" "os" "path/filepath" "github.com/zeusyf/btcd/blockchain" "github.com/zeusyf/btcd/chaincfg" "github.com/zeusyf/btcd/database" "github.com/zeusyf/btcutil" _ "github.com/zeusyf/btcd/database/ffldb" ) func main() { // Create a new database to store the accepted blocks into. Typically // this would be opening an existing database and would not be deleting // and creating a new database like this, but it is done here so this is // a complete working example and does not leave temporary files laying // around. dbPath := filepath.Join(os.TempDir(), "exampleprocessblock") _ = os.RemoveAll(dbPath) db, err := database.Create("ffldb", dbPath, chaincfg.MainNetParams.Net) if err != nil { fmt.Printf("Failed to create database: %v\n", err) return } defer os.RemoveAll(dbPath) defer db.Close() // Create a new BlockChain instance using the underlying database for // the main bitcoin network. This example does not demonstrate some // of the other available configuration options such as specifying a // notification callback and signature cache. Also, the caller would // ordinarily keep a reference to the median time source and add time // values obtained from other peers on the network so the local time is // adjusted to be in agreement with other peers. chain, err := blockchain.New(&blockchain.Config{ DB: db, ChainParams: &chaincfg.MainNetParams, TimeSource: blockchain.NewMedianTime(), }) if err != nil { fmt.Printf("Failed to create chain instance: %v\n", err) return } // Process a block. For this example, we are going to intentionally // cause an error by trying to process the genesis block which already // exists. genesisBlock := btcutil.NewBlock(chaincfg.MainNetParams.GenesisBlock) isMainChain, isOrphan, err := chain.ProcessBlock(genesisBlock, blockchain.BFNone) if err != nil { fmt.Printf("Failed to process block: %v\n", err) return } fmt.Printf("Block accepted. Is it on the main chain?: %v", isMainChain) fmt.Printf("Block accepted. Is it an orphan?: %v", isOrphan) }
Output: Failed to process block: already have block 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
func (*BlockChain) ProcessOrphans ¶
func (b *BlockChain) ProcessOrphans(hash *chainhash.Hash, flags BehaviorFlags) error
ProcessOrphans determines if there are any Orphans which depend on the passed block hash (they are no longer Orphans if true) and potentially accepts them. It repeats the process for the newly accepted blocks (to detect further Orphans which may no longer be Orphans) until there are no more.
The flags do not modify the behavior of this function directly, however they are needed to pass along to maybeAcceptBlock.
This function MUST be called with the chain state lock held (for writes).
func (*BlockChain) Rebuildutxo ¶
func (b *BlockChain) Rebuildutxo(index indexer)
func (*BlockChain) ReorganizeChain ¶
func (b *BlockChain) ReorganizeChain(detachNodes, attachNodes *list.List) error
ReorganizeChain reorganizes the block chain by disconnecting the nodes in the detachNodes list and connecting the nodes in the attach list. It expects that the lists are already in the correct order and are in sync with the end of the current best chain. Specifically, nodes that are being disconnected must be in reverse order (think of popping them off the end of the chain) and nodes the are being attached must be in forwards order (think pushing them onto the end of the chain).
This function may modify node statuses in the block index without flushing.
This function MUST be called with the chain state lock held (for writes).
func (*BlockChain) SendNotification ¶
func (b *BlockChain) SendNotification(typ NotificationType, data interface{})
sendNotification sends a notification with the passed type and data if the caller requested notifications by providing a callback function in the call to New.
func (*BlockChain) SideChainContains ¶
func (*BlockChain) SignedBy ¶
func (b *BlockChain) SignedBy(x *list.Element, miners []*[20]byte) bool
func (*BlockChain) Subscribe ¶
func (b *BlockChain) Subscribe(callback NotificationCallback) int
Subscribe to block chain notifications. Registers a callback to be executed when various events take place. See the documentation on Notification and NotificationType for details on the types and contents of notifications.
func (*BlockChain) TotalRotate ¶
func (b *BlockChain) TotalRotate(lst *list.List) int32
func (*BlockChain) TphNotice ¶
func (b *BlockChain) TphNotice(t *Notification)
func (*BlockChain) TryConnectOrphan ¶
func (b *BlockChain) TryConnectOrphan(hash *chainhash.Hash) bool
func (*BlockChain) TxInMainChain ¶
func (b *BlockChain) TxInMainChain(txHash *chainhash.Hash, height int32) bool
type Config ¶
type Config struct { // DB defines the database which houses the blocks and will be used to // store all metadata created by this package such as the utxo set. // // This field is required. DB database.DB MinerDB database.DB // Interrupt specifies a channel the caller can close to signal that // long running operations, such as catching up indexes or performing // database migrations, should be interrupted. // // This field can be nil if the caller does not desire the behavior. Interrupt <-chan struct{} // ChainParams identifies which chain parameters the chain is associated // with. // // This field is required. ChainParams *chaincfg.Params // Checkpoints hold caller-defined checkpoints that should be added to // the default checkpoints in ChainParams. Checkpoints must be sorted // by height. // // This field can be nil if the caller does not wish to specify any // checkpoints. Checkpoints []chaincfg.Checkpoint // TimeSource defines the median time source to use for things such as // block processing and determining whether or not the chain is current. // // The caller is expected to keep a reference to the time source as well // and add time samples from other peers on the network so the local // time is adjusted to be in agreement with other peers. TimeSource chainutil.MedianTimeSource // IndexManager defines an index manager to use when initializing the // chain and connecting and disconnecting blocks. // // This field can be nil if the caller does not wish to make use of an // index manager. IndexManager IndexManager Miner []btcutil.Address PrivKey []*btcec.PrivateKey // HashCache defines a transaction hash mid-state cache to use when // validating transactions. This cache has the potential to greatly // speed up transaction validation as re-using the pre-calculated // mid-state eliminates the O(N^2) validation complexity due to the // SigHashAll flag. // // This field can be nil if the caller is not interested in using a // signature cache. // HashCache *txscript.HashCache AddrUsage func(address btcutil.Address) uint32 }
Config is a descriptor which specifies the blockchain instance configuration.
type DeploymentError ¶
type DeploymentError uint32
DeploymentError identifies an error that indicates a deployment ID was specified that does not exist.
func (DeploymentError) Error ¶
func (e DeploymentError) Error() string
Error returns the assertion error as a human-readable string and satisfies the error interface.
type ErrorCode ¶
type ErrorCode int
ErrorCode identifies a kind of error.
const ( // ErrDuplicateBlock indicates a block with the same hash already // exists. ErrDuplicateBlock ErrorCode = iota // ErrBlockTooBig indicates the serialized block size exceeds the // maximum allowed size. ErrBlockTooBig // ErrBlockWeightTooHigh indicates that the block's computed weight // metric exceeds the maximum allowed value. ErrBlockWeightTooHigh // ErrBlockVersionTooOld indicates the block version is too old and is // no longer accepted since the majority of the network has upgraded // to a newer version. ErrBlockVersionTooOld // ErrInvalidTime indicates the time in the passed block has a precision // that is more than one second. The chain consensus rules require // timestamps to have a maximum precision of one second. ErrInvalidTime // ErrTimeTooOld indicates the time is either before the median time of // the last several blocks per the chain consensus rules or prior to the // most recent checkpoint. ErrTimeTooOld // ErrTimeTooNew indicates the time is too far in the future as compared // the current time. ErrTimeTooNew // ErrDifficultyTooLow indicates the difficulty for the block is lower // than the difficulty required by the most recent checkpoint. ErrDifficultyTooLow // ErrUnexpectedDifficulty indicates specified bits do not align with // the expected value either because it doesn't match the calculated // valued based on difficulty regarted rules or it is out of the valid // range. ErrUnexpectedDifficulty // ErrHighHash indicates the block does not hash to a value which is // lower than the required target difficultly. ErrHighHash // ErrBadMerkleRoot indicates the calculated merkle root does not match // the expected value. ErrBadMerkleRoot // ErrBadCheckpoint indicates a block that is expected to be at a // checkpoint height does not match the expected one. ErrBadCheckpoint // ErrForkTooOld indicates a block is attempting to fork the block chain // before the most recent checkpoint. ErrForkTooOld // ErrCheckpointTimeTooOld indicates a block has a timestamp before the // most recent checkpoint. ErrCheckpointTimeTooOld // ErrNoTransactions indicates the block does not have a least one // transaction. A valid block must have at least the coinbase // transaction. ErrNoTransactions // ErrNoTxInputs indicates a transaction does not have any inputs. A // valid transaction must have at least one input. ErrNoTxInputs // ErrNoTxOutputs indicates a transaction does not have any outputs. A // valid transaction must have at least one output. ErrNoTxOutputs // ErrTxTooBig indicates a transaction exceeds the maximum allowed size // when serialized. ErrTxTooBig // ErrBadTxOutValue indicates an output value for a transaction is // invalid in some way such as being out of range. ErrBadTxOutValue // ErrDuplicateTxInputs indicates a transaction references the same // input more than once. ErrDuplicateTxInputs // ErrBadTxInput indicates a transaction input is invalid in some way // such as referencing a previous transaction outpoint which is out of // range or not referencing one at all. ErrBadTxInput // ErrMissingTxOut indicates a transaction output referenced by an input // either does not exist or has already been spent. ErrMissingTxOut // ErrUnfinalizedTx indicates a transaction has not been finalized. // A valid block may only contain finalized transactions. ErrUnfinalizedTx // ErrDuplicateTx indicates a block contains an identical transaction // (or at least two transactions which hash to the same value). A // valid block may only contain unique transactions. ErrDuplicateTx // ErrOverwriteTx indicates a block contains a transaction that has // the same hash as a previous transaction which has not been fully // spent. ErrOverwriteTx // ErrImmatureSpend indicates a transaction is attempting to spend a // coinbase that has not yet reached the required maturity. ErrImmatureSpend // ErrSpendTooHigh indicates a transaction is attempting to spend more // value than the sum of all of its inputs. ErrSpendTooHigh // ErrBadFees indicates the total fees for a block are invalid due to // exceeding the maximum possible value. ErrBadFees // ErrTooManySigOps indicates the total number of signature operations // for a transaction or block exceed the maximum allowed limits. ErrTooManySigOps // ErrFirstTxNotCoinbase indicates the first transaction in a block // is not a coinbase transaction. ErrFirstTxNotCoinbase // ErrMultipleCoinbases indicates a block contains more than one // coinbase transaction. ErrMultipleCoinbases // ErrBadCoinbaseScriptLen indicates the length of the signature script // for a coinbase transaction is not within the valid range. ErrBadCoinbaseScriptLen // ErrBadCoinbaseValue indicates the amount of a coinbase value does // not match the expected value of the subsidy plus the sum of all fees. ErrBadCoinbaseValue // ErrMissingCoinbaseHeight indicates the coinbase transaction for a // block does not start with the serialized block block height as // required for version 2 and higher blocks. ErrMissingCoinbaseHeight // ErrBadCoinbaseHeight indicates the serialized block height in the // coinbase transaction for version 2 and higher blocks does not match // the expected value. ErrBadCoinbaseHeight // ErrScriptMalformed indicates a transaction script is malformed in // some way. For example, it might be longer than the maximum allowed // length or fail to parse. ErrScriptMalformed // ErrScriptValidation indicates the result of executing transaction // script failed. The error covers any failure when executing scripts // such signature verification failures and execution past the end of // the stack. ErrScriptValidation // ErrUnexpectedWitness indicates that a block includes transactions // with witness data, but doesn't also have a witness commitment within // the coinbase transaction. ErrUnexpectedWitness // ErrInvalidWitnessCommitment indicates that a block's witness // commitment is not well formed. ErrInvalidWitnessCommitment // ErrWitnessCommitmentMismatch indicates that the witness commitment // included in the block's coinbase transaction doesn't match the // manually computed witness commitment. ErrWitnessCommitmentMismatch // ErrPreviousBlockUnknown indicates that the previous block is not known. ErrPreviousBlockUnknown // ErrInvalidAncestorBlock indicates that an ancestor of this block has // already failed validation. ErrInvalidAncestorBlock // ErrPrevBlockNotBest indicates that the block's previous block is not the // current chain tip. This is not a block validation rule, but is required // for block proposals submitted via getblocktemplate RPC. ErrPrevBlockNotBest ErrExcessContractExec ErrBlockTimeOutOfOrder ErrExpiredTx )
These constants are used to identify a specific RuleError.
type IndexManager ¶
type IndexManager interface { // BlockInit is invoked during chain initialize in order to allow the index // manager to initialize itself and any indexes it is managing. The // channel parameter specifies a channel the caller can close to signal // that the process should be interrupted. It can be nil if that // behavior is not desired. Init(*BlockChain, <-chan struct{}) error // ConnectBlock is invoked when a new block has been connected to the // main chain. The set of output spent within a block is also passed in // so indexers can access the previous output scripts input spent if // required. ConnectBlock(database.Tx, *btcutil.Block, []viewpoint.SpentTxOut) error // DisconnectBlock is invoked when a block has been disconnected from // the main chain. The set of outputs scripts that were spent within // this block is also returned so indexers can clean up the prior index // state for this block. DisconnectBlock(database.Tx, *btcutil.Block, []viewpoint.SpentTxOut) error // get TxBlockRegion TxBlockRegion(hash *chainhash.Hash) (*database.BlockRegion, error) }
IndexManager provides a generic interface that the is called when blocks are connected and disconnected to and from the tip of the main chain for the purpose of supporting optional indexes.
type MinerChain ¶
type MinerChain interface { ProcessBlock(*wire.MinerBlock, BehaviorFlags) (bool, bool, error, wire.Message) BestSnapshot() *BestState BlockByHash(hash *chainhash.Hash) (*wire.MinerBlock, error) DBBlockByHash(hash *chainhash.Hash) (*wire.MinerBlock, error) NodeByHash(hash *chainhash.Hash) *chainutil.BlockNode DeepNodeByHash(hash *chainhash.Hash) *chainutil.BlockNode NodeByHeight(height int32) *chainutil.BlockNode BlockByHeight(height int32) (*wire.MinerBlock, error) CheckConnectBlockTemplate(*wire.MinerBlock) error CalcNextRequiredDifficulty(timestamp time.Time) (uint32, uint32, error) ProcessOrphans(*chainhash.Hash, BehaviorFlags) (error, wire.Message) IsCurrent() bool Subscribe(callback NotificationCallback) Tip() *wire.MinerBlock DisconnectTip() CalcNextBlockVersion() (uint32, error) IsDeploymentActive(uint32) (bool, error) HaveBlock(hash *chainhash.Hash) (bool, error) NextRequiredDifficulty(lastNode *chainutil.BlockNode, newBlockTime time.Time) (uint32, uint32, error) NextBlockVersion(prevNode *chainutil.BlockNode) (uint32, error) NodetoHeader(node *chainutil.BlockNode) wire.MingingRightBlock TphReport(rpts int, last *chainutil.BlockNode, me [20]byte) []uint32 DSReport(*wire.Violations) FastReorganizeChain(attachNodes *list.List) error TPSreportFromDB([20]byte, uint32) []TPSrv }
type Notification ¶
type Notification struct { Type NotificationType Data interface{} }
Notification defines notification that is sent to the caller via the callback function provided during the call to New and consists of a notification type as well as associated data that depends on the type as follows:
- NTBlockAccepted: *btcutil.Block
- NTBlockConnected: *btcutil.Block
- NTBlockDisconnected: *btcutil.Block
type NotificationCallback ¶
type NotificationCallback func(*Notification)
NotificationCallback is used for a caller to provide a callback for notifications about various chain events.
type NotificationType ¶
type NotificationType int
NotificationType represents the type of a notification message.
const ( // NTBlockAccepted indicates the associated block was accepted into // the block chain. Note that this does not necessarily mean it was // added to the main chain. For that, use NTBlockConnected. NTBlockAccepted NotificationType = iota // NTBlockConnected indicates the associated block was connected to the // main chain. NTBlockConnected // NTBlockDisconnected indicates the associated block was disconnected // from the main chain. NTBlockDisconnected // NTBlockRejected indicates the associated block was rejected. NTBlockRejected )
Constants for the type of a notification message.
func (NotificationType) String ¶
func (n NotificationType) String() string
String returns the NotificationType in human-readable form.
type RuleError ¶
type RuleError struct { ErrorCode ErrorCode // Describes the kind of error Description string // Human readable description of the issue }
RuleError identifies a rule violation. It is used to indicate that processing of a block or transaction failed due to one of the many validation rules. The caller can use type assertions to determine if a failure was specifically due to a rule violation and access the ErrorCode field to ascertain the specific reason for the rule violation.
type SequenceLock ¶
SequenceLock represents the converted relative lock-time in seconds, and absolute block-height for a transaction input's relative lock-times. According to SequenceLock, after the referenced input has been confirmed within a block, a transaction spending that input can be included into a block either after 'seconds' (according to past median time), or once the 'BlockHeight' has been reached.