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 BigToCompact(n *big.Int) uint32
- func BuildMerkleTreeStore(transactions []*util.Tx, witness bool) []*chainhash.Hash
- func CalcBlockSubsidy(height int32, chainParams *netparams.Params) (r int64)
- func CalcWork(bits uint32, height int32, algover int32) *big.Int
- func CheckBlockSanity(block *util.Block, powLimit *big.Int, timeSource MedianTimeSource, ...) error
- func CheckProofOfWork(block *util.Block, powLimit *big.Int, height int32) error
- func CheckTransactionInputs(tx *util.Tx, txHeight int32, utxoView *UtxoViewpoint, ...) (int64, error)
- func CheckTransactionSanity(tx *util.Tx) error
- func CompactToBig(compact uint32) *big.Int
- func ContainsBlacklisted(b *BlockChain, tx *util.Tx, blacklist []util.Address) (hasBlacklisted bool)
- func CountP2SHSigOps(tx *util.Tx, isCoinBaseTx bool, utxoView *UtxoViewpoint) (int, error)
- func CountSigOps(tx *util.Tx) int
- func ExtractCoinbaseHeight(coinbaseTx *util.Tx) (int32, error)
- func ExtractWitnessCommitment(tx *util.Tx) ([]byte, bool)
- func GetBlockWeight(blk *util.Block) int64
- func GetSigOpCost(tx *util.Tx, isCoinBaseTx bool, utxoView *UtxoViewpoint, bip16, segWit bool) (int, error)
- func GetTransactionWeight(tx *util.Tx) int64
- func HashMerkleBranches(left *chainhash.Hash, right *chainhash.Hash) *chainhash.Hash
- func HashToBig(hash *chainhash.Hash) *big.Int
- func Intersects(a, b []util.Address) bool
- func IsCoinBase(tx *util.Tx) bool
- func IsCoinBaseTx(msgTx *wire.MsgTx) bool
- func IsFinalizedTransaction(tx *util.Tx, blockHeight int32, blockTime time.Time) bool
- func LockTimeToSequence(isSeconds bool, locktime uint32) uint32
- func RightJustify(s string, w int) string
- func SequenceLockActive(sequenceLock *SequenceLock, blockHeight int32, medianTimePast time.Time) bool
- func ShouldHaveSerializedBlockHeight(header *wire.BlockHeader) bool
- func ValidateTransactionScripts(b *BlockChain, tx *util.Tx, utxoView *UtxoViewpoint, ...) error
- func ValidateWitnessCommitment(blk *util.Block) error
- type AssertError
- type BehaviorFlags
- type BestState
- type BlockChain
- func (b *BlockChain) BestSnapshot() *BestState
- func (b *BlockChain) BlockByHash(hash *chainhash.Hash) (*util.Block, error)
- func (b *BlockChain) BlockByHeight(blockHeight int32) (*util.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) BlockLocator
- func (b *BlockChain) CalcNextBlockVersion() (uint32, error)
- func (b *BlockChain) CalcNextRequiredDifficulty(workerNumber uint32, timestamp ..., algo string) (difficulty uint32, err error)
- func (b *BlockChain) CalcNextRequiredDifficultyHalcyon(workerNumber uint32, lastNode *BlockNode, newBlockTime time.Time, ...) (newTargetBits uint32, err error)
- func (b *BlockChain) CalcNextRequiredDifficultyPlan9(workerNumber uint32, lastNode *BlockNode, newBlockTime time.Time, ...) (newTargetBits uint32, adjustment float64, err error)
- func (b *BlockChain) CalcNextRequiredDifficultyPlan9Controller(lastNode *BlockNode) (newTargetBits *map[int32]uint32, err error)
- func (b *BlockChain) CalcSequenceLock(tx *util.Tx, utxoView *UtxoViewpoint, mempool bool) (*SequenceLock, error)
- func (b *BlockChain) CheckConnectBlockTemplate(workerNumber uint32, block ...) error
- func (b *BlockChain) Checkpoints() []chaincfg.Checkpoint
- func (b *BlockChain) FetchSpendJournal(targetBlock *util.Block) ([]SpentTxOut, error)
- func (b *BlockChain) FetchUtxoEntry(outpoint wire.OutPoint) (*UtxoEntry, error)
- func (b *BlockChain) FetchUtxoView(tx *util.Tx) (*UtxoViewpoint, error)
- func (b *BlockChain) GetCommonP9Averages(lastNode *BlockNode, nH int32) (allTimeAv, allTimeDiv, qhourDiv, hourDiv, dayDiv float64)
- func (b *BlockChain) GetOrphanRoot(hash *chainhash.Hash) *chainhash.Hash
- func (b *BlockChain) GetP9AlgoDiv(allTimeDiv float64, last *BlockNode, startHeight int32, algoVer int32, ...) (algDiv float64)
- func (b *BlockChain) GetP9Since(lastNode *BlockNode, algoVer int32) (since, ttpb, timeSinceAlgo float64, startHeight int32, last *BlockNode)
- func (b *BlockChain) HasCheckpoints() bool
- func (b *BlockChain) HaveBlock(hash *chainhash.Hash) (bool, error)
- func (b *BlockChain) HeaderByHash(hash *chainhash.Hash) (wire.BlockHeader, error)
- func (b *BlockChain) HeightRange(startHeight, endHeight int32) ([]..., error)
- func (b *BlockChain) HeightToHashRange(startHeight int32, endHash *chainhash.Hash, maxResults int) ([]chainhash.Hash, error)
- func (b *BlockChain) IntervalBlockHashes(endHash *chainhash.Hash, interval int) ([]chainhash.Hash, error)
- func (b *BlockChain) IsCheckpointCandidate(block *util.Block) (bool, error)
- func (b *BlockChain) IsCurrent() bool
- func (b *BlockChain) IsDeploymentActive(deploymentID uint32) (bool, error)
- func (b *BlockChain) IsKnownOrphan(hash *chainhash.Hash) bool
- func (b *BlockChain) IsP9HardFork(nH int32) bool
- func (b *BlockChain) LatestBlockLocator() (BlockLocator, error)
- func (b *BlockChain) LatestCheckpoint() *chaincfg.Checkpoint
- func (b *BlockChain) LocateBlocks(locator BlockLocator, hashStop *chainhash.Hash, maxHashes uint32) []chainhash.Hash
- func (b *BlockChain) LocateHeaders(locator BlockLocator, hashStop *chainhash.Hash) []wire.BlockHeader
- func (b *BlockChain) MainChainHasBlock(hash *chainhash.Hash) bool
- func (b *BlockChain) ProcessBlock(workerNumber uint32, block *util.Block, flags BehaviorFlags, height int32) (bool, bool, error)
- func (b *BlockChain) Subscribe(callback NotificationCallback)
- func (b *BlockChain) ThresholdState(deploymentID uint32) (ThresholdState, error)
- type BlockLocator
- type BlockNode
- func (node *BlockNode) Ancestor(height int32) *BlockNode
- func (node *BlockNode) CalcPastMedianTime() time.Time
- func (node *BlockNode) GetAlgo() int32
- func (node *BlockNode) GetLastWithAlgo(algo int32) (prev *BlockNode)
- func (node *BlockNode) Header() wire.BlockHeader
- func (node *BlockNode) RelativeAncestor(distance int32) *BlockNode
- type Config
- type DeploymentError
- type ErrorCode
- type IndexManager
- type MedianTimeSource
- type Notification
- type NotificationCallback
- type NotificationType
- type RuleError
- type SequenceLock
- type SpentTxOut
- type ThresholdState
- type UtxoEntry
- type UtxoViewpoint
- func (view *UtxoViewpoint) AddTxOut(tx *util.Tx, txOutIdx uint32, blockHeight int32)
- func (view *UtxoViewpoint) AddTxOuts(tx *util.Tx, blockHeight int32)
- func (view *UtxoViewpoint) BestHash() *chainhash.Hash
- func (view *UtxoViewpoint) Entries() map[wire.OutPoint]*UtxoEntry
- func (view *UtxoViewpoint) LookupEntry(outpoint wire.OutPoint) *UtxoEntry
- func (view *UtxoViewpoint) RemoveEntry(outpoint wire.OutPoint)
- func (view *UtxoViewpoint) SetBestHash(hash *chainhash.Hash)
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 ( // 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 // MinCoinbaseScriptLen is the minimum length a coinbase script can be. MinCoinbaseScriptLen = 2 // MaxCoinbaseScriptLen is the maximum length a coinbase script can be. MaxCoinbaseScriptLen = 100 )
const ( // MaxBlockWeight defines the maximum block weight, where "block weight" is interpreted as defined in BIP0141. A block's weight is calculated as the sum of the of bytes in the existing transactions and header, plus the weight of each byte within a transaction. The weight of a "base" byte is 4, while the weight of a witness byte is 1. As a result, for a block to be valid, the BlockWeight MUST be less than, or equal to MaxBlockWeight. MaxBlockWeight = 4000000 // MaxBlockBaseSize is the maximum number of bytes within a block which can be allocated to non-witness data. MaxBlockBaseSize = 1000000 // MaxBlockSigOpsCost is the maximum number of signature operations allowed for a block. It is calculated via a weighted algorithm which weights segregated witness sig ops lower than regular sig ops. MaxBlockSigOpsCost = 80000 // WitnessScaleFactor determines the level of "discount" witness data receives compared to "base" data. A scale factor of 4, denotes that witness data is 1/4 as cheap as regular non-witness data. WitnessScaleFactor = 4 // MinTxOutputWeight is the minimum possible weight for a transaction output. MinTxOutputWeight = WitnessScaleFactor * wire.MinTxOutPayload // MaxOutputsPerBlock is the maximum number of transaction outputs there can be in a block of max weight size. MaxOutputsPerBlock = MaxBlockWeight / MinTxOutputWeight )
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. TODO: review this and add it to the fork spec
Variables ¶
var ( // ScryptPowLimit is ScryptPowLimit = scryptPowLimit // ScryptPowLimitBits is ScryptPowLimitBits = BigToCompact(&scryptPowLimit) )
var ( // WitnessMagicBytes is the prefix marker within the public key script of a coinbase output to indicate that this output holds the witness commitment for a block. WitnessMagicBytes = []byte{ txscript.OP_RETURN, txscript.OP_DATA_36, 0xaa, 0x21, 0xa9, 0xed, } )
Functions ¶
func BigToCompact ¶
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" blockchain "github.com/p9c/pod/pkg/chain" _ "github.com/p9c/pod/pkg/db/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 BuildMerkleTreeStore ¶
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 ¶
func CheckBlockSanity ¶
func CheckProofOfWork ¶
func CheckTransactionInputs ¶
func CheckTransactionSanity ¶
func CompactToBig ¶
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" blockchain "github.com/p9c/pod/pkg/chain" _ "github.com/p9c/pod/pkg/db/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 ContainsBlacklisted ¶
func ContainsBlacklisted(b *BlockChain, tx *util.Tx, blacklist []util.Address) (hasBlacklisted bool)
ContainsBlacklisted returns true if one of the given addresses is found in the transaction
func CountP2SHSigOps ¶
func CountSigOps ¶
func ExtractWitnessCommitment ¶
ExtractWitnessCommitment attempts to locate, and return the witness commitment for a block. The witness commitment is of the form: SHA256(witness root || witness nonce). The function additionally returns a boolean indicating if the witness root was located within any of the txOut's in the passed transaction. The witness commitment is stored as the data push for an OP_RETURN with special magic bytes to aide in location.
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 *util.Tx, isCoinBaseTx bool, utxoView *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 Intersects ¶
Intersects returns whether one slice of byte slices contains a match in another
func IsCoinBase ¶
func IsCoinBaseTx ¶
func IsFinalizedTransaction ¶
func LockTimeToSequence ¶
func RightJustify ¶
func SequenceLockActive ¶
func SequenceLockActive(sequenceLock *SequenceLock, blockHeight int32, medianTimePast time.Time) bool
func ShouldHaveSerializedBlockHeight ¶
func ShouldHaveSerializedBlockHeight(header *wire.BlockHeader) bool
func ValidateTransactionScripts ¶
func ValidateTransactionScripts(b *BlockChain, tx *util.Tx, utxoView *UtxoViewpoint, flags txscript.ScriptFlags, sigCache *txscript.SigCache, hashCache *txscript.HashCache) error
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
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 // 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. Version int32 Bits uint32 // The difficulty bits of the block. BlockSize uint64 // The size of the block. BlockWeight uint64 // The weight of the block. NumTxns uint64 // The number of txns in the block. TotalTxns uint64 // The total number of txns in the chain. MedianTime time.Time // Median time as per CalcPastMedianTime. }
type BlockChain ¶
type BlockChain struct { // These fields are related to the memory block index. // They both have their own locks, // however they are often also protected by the chain lock to help // prevent logic races when blocks are being processed. // index houses the entire block index in memory. // The block index is a tree-shaped structure. // BestChain tracks the current active chain by making use of an // efficient chain view into the block index. Index *blockIndex BestChain *chainView // DifficultyAdjustments keeps track of the latest difficulty adjustment // for each algorithm DifficultyAdjustments map[string]float64 // contains filtered or unexported fields }
func New ¶
func New(config *Config) (*BlockChain, error)
func (*BlockChain) BestSnapshot ¶
func (b *BlockChain) BestSnapshot() *BestState
func (*BlockChain) BlockByHash ¶
func (*BlockChain) BlockByHeight ¶
func (b *BlockChain) BlockByHeight(blockHeight int32) (*util.Block, error)
func (*BlockChain) BlockHashByHeight ¶
func (b *BlockChain) BlockHashByHeight(blockHeight int32) (*chainhash.Hash, error)
func (*BlockChain) BlockHeightByHash ¶
func (b *BlockChain) BlockHeightByHash(hash *chainhash.Hash) (int32, error)
func (*BlockChain) BlockLocatorFromHash ¶
func (b *BlockChain) BlockLocatorFromHash(hash *chainhash.Hash) BlockLocator
func (*BlockChain) CalcNextBlockVersion ¶
func (b *BlockChain) CalcNextBlockVersion() (uint32, error)
func (*BlockChain) CalcNextRequiredDifficulty ¶
func (*BlockChain) CalcNextRequiredDifficultyHalcyon ¶
func (b *BlockChain) CalcNextRequiredDifficultyHalcyon( workerNumber uint32, lastNode *BlockNode, newBlockTime time.Time, algoname string, l bool) (newTargetBits uint32, err error)
calcNextRequiredDifficultyHalcyon calculates the required difficulty for the block after the passed previous block node based on the difficulty retarget rules. This function differs from the exported CalcNextRequiredDifficulty in that the exported version uses the current best chain as the previous block node while this function accepts any block node.
func (*BlockChain) CalcNextRequiredDifficultyPlan9 ¶
func (b *BlockChain) CalcNextRequiredDifficultyPlan9(workerNumber uint32, lastNode *BlockNode, newBlockTime time.Time, algoname string, l bool) (newTargetBits uint32, adjustment float64, err error)
CalcNextRequiredDifficultyPlan9 calculates the required difficulty for the block after the passed previous block node based on the difficulty retarget rules. This function differs from the exported CalcNextRequiredDifficulty in that the exported version uses the current best chain as the previous block node while this function accepts any block node.
func (*BlockChain) CalcNextRequiredDifficultyPlan9Controller ¶
func (b *BlockChain) CalcNextRequiredDifficultyPlan9Controller( lastNode *BlockNode) (newTargetBits *map[int32]uint32, err error)
CalcNextRequiredDifficultyPlan9Controller returns all of the algorithm difficulty targets for sending out with the other pieces required to construct a block, as these numbers are generated from block timestamps
func (*BlockChain) CalcSequenceLock ¶
func (b *BlockChain) CalcSequenceLock(tx *util.Tx, utxoView *UtxoViewpoint, mempool bool) (*SequenceLock, error)
func (*BlockChain) CheckConnectBlockTemplate ¶
func (b *BlockChain) CheckConnectBlockTemplate(workerNumber uint32, block *util. 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) Checkpoints ¶
func (b *BlockChain) Checkpoints() []chaincfg.Checkpoint
func (*BlockChain) FetchSpendJournal ¶
func (b *BlockChain) FetchSpendJournal(targetBlock *util.Block) ([]SpentTxOut, error)
func (*BlockChain) FetchUtxoEntry ¶
func (b *BlockChain) FetchUtxoEntry(outpoint wire.OutPoint) (*UtxoEntry, error)
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 *util.Tx) (*UtxoViewpoint, 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) GetCommonP9Averages ¶
func (b *BlockChain) GetCommonP9Averages(lastNode *BlockNode, nH int32) (allTimeAv, allTimeDiv, qhourDiv, hourDiv, dayDiv float64)
func (*BlockChain) GetOrphanRoot ¶
func (b *BlockChain) GetOrphanRoot(hash *chainhash.Hash) *chainhash.Hash
func (*BlockChain) GetP9AlgoDiv ¶
func (*BlockChain) GetP9Since ¶
func (*BlockChain) HasCheckpoints ¶
func (b *BlockChain) HasCheckpoints() bool
func (*BlockChain) HeaderByHash ¶
func (b *BlockChain) HeaderByHash(hash *chainhash.Hash) (wire.BlockHeader, error)
func (*BlockChain) HeightRange ¶
func (b *BlockChain) HeightRange(startHeight, endHeight int32) ([]chainhash. Hash, error)
func (*BlockChain) HeightToHashRange ¶
func (*BlockChain) IntervalBlockHashes ¶
func (*BlockChain) IsCheckpointCandidate ¶
func (b *BlockChain) IsCheckpointCandidate(block *util.Block) (bool, error)
func (*BlockChain) IsCurrent ¶
func (b *BlockChain) IsCurrent() bool
func (*BlockChain) IsDeploymentActive ¶
func (b *BlockChain) IsDeploymentActive(deploymentID uint32) (bool, error)
IsDeploymentActive returns true if the target deploymentID is active, and false otherwise. This function is safe for concurrent access.
func (*BlockChain) IsKnownOrphan ¶
func (b *BlockChain) IsKnownOrphan(hash *chainhash.Hash) bool
func (*BlockChain) IsP9HardFork ¶
func (b *BlockChain) IsP9HardFork(nH int32) bool
func (*BlockChain) LatestBlockLocator ¶
func (b *BlockChain) LatestBlockLocator() (BlockLocator, error)
func (*BlockChain) LatestCheckpoint ¶
func (b *BlockChain) LatestCheckpoint() *chaincfg.Checkpoint
func (*BlockChain) LocateBlocks ¶
func (b *BlockChain) LocateBlocks(locator BlockLocator, hashStop *chainhash.Hash, maxHashes uint32) []chainhash.Hash
func (*BlockChain) LocateHeaders ¶
func (b *BlockChain) LocateHeaders(locator BlockLocator, hashStop *chainhash.Hash) []wire.BlockHeader
func (*BlockChain) MainChainHasBlock ¶
func (b *BlockChain) MainChainHasBlock(hash *chainhash.Hash) bool
func (*BlockChain) ProcessBlock ¶
func (b *BlockChain) ProcessBlock(workerNumber uint32, block *util.Block, flags BehaviorFlags, height int32) (bool, bool, error)
func (*BlockChain) Subscribe ¶
func (b *BlockChain) Subscribe(callback NotificationCallback)
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) ThresholdState ¶
func (b *BlockChain) ThresholdState(deploymentID uint32) (ThresholdState, error)
ThresholdState returns the current rule change threshold state of the given deployment ID for the block AFTER the end of the current best chain. This function is safe for concurrent access.
type BlockLocator ¶
type BlockNode ¶
type BlockNode struct { // Diffs is the computed difficulty targets for a block to be connected // to this one Diffs *map[int32]uint32 DiffMx sync.Mutex // contains filtered or unexported fields }
BlockNode represents a block within the block chain and is primarily used to aid in selecting the best chain to be the main chain. The main chain is stored into the block database.
func NewBlockNode ¶
func NewBlockNode(blockHeader *wire.BlockHeader, parent *BlockNode) *BlockNode
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 (*BlockNode) Ancestor ¶
Ancestor returns the ancestor block node at the provided height by following the chain backwards from this node. The returned block will be nil when a height is requested that is after the height of the passed node or is less than zero. This function is safe for concurrent access.
func (*BlockNode) CalcPastMedianTime ¶
CalcPastMedianTime calculates the median time of the previous few blocks prior to, and including, the block node. This function is safe for concurrent access.
func (*BlockNode) GetLastWithAlgo ¶
GetLastWithAlgo returns the newest block from node with specified algo
func (*BlockNode) Header ¶
func (node *BlockNode) Header() wire.BlockHeader
Header constructs a block header from the node and returns it. This function is safe for concurrent access.
func (*BlockNode) RelativeAncestor ¶
RelativeAncestor returns the ancestor block node a relative 'distance' blocks before this node. This is equivalent to calling Ancestor with the node's height minus provided distance. This function is safe for concurrent access.
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 // 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 *netparams.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 MedianTimeSource // SigCache defines a signature cache to use when when validating // signatures. This is typically most useful when individual // transactions are already being validated prior to their inclusion in a // block such as what is usually done via a transaction memory pool. // This field can be nil if the caller is not interested in using a // signature cache. SigCache *txscript.SigCache // 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 // 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 }
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 // ErrBlacklisted indicates a transaction contains a blacklisted address ErrBlacklisted )
These constants are used to identify a specific RuleError.
type IndexManager ¶
type IndexManager interface { // Init 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, *util.Block, []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, *util.Block, []SpentTxOut) 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 MedianTimeSource ¶
type MedianTimeSource interface { // AdjustedTime returns the current time adjusted by the median time offset // as calculated from the time samples added by AddTimeSample. AdjustedTime() time.Time // AddTimeSample adds a time sample that is used when determining the median // time of the added samples. AddTimeSample(id string, timeVal time.Time) // Offset returns the number of seconds to adjust the local clock based upon // the median of the time samples added by AddTimeData. Offset() time.Duration }
func NewMedianTime ¶
func NewMedianTime() MedianTimeSource
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: *util.Block
- NTBlockConnected: *util.Block
- NTBlockDisconnected: *util.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 )
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 ¶
type SpentTxOut ¶
type ThresholdState ¶
type ThresholdState byte
ThresholdState define the various threshold states used when voting on consensus changes.
const ( // ThresholdDefined is the first state for each deployment and is the state for the genesis block has by definition for all deployments. ThresholdDefined ThresholdState = iota // ThresholdStarted is the state for a deployment once its start time has been reached. ThresholdStarted // ThresholdLockedIn is the state for a deployment during the retarget period which is after the ThresholdStarted state period and the number of blocks that have voted for the deployment equal or exceed the required number of votes for the deployment. ThresholdLockedIn // ThresholdActive is the state for a deployment for all blocks after a retarget period in which the deployment was in the ThresholdLockedIn state. ThresholdActive // ThresholdFailed is the state for a deployment once its expiration time has been reached and it did not reach the ThresholdLockedIn state. ThresholdFailed )
These constants are used to identify specific threshold states.
func (ThresholdState) String ¶
func (t ThresholdState) String() string
String returns the ThresholdState as a human-readable name.
type UtxoEntry ¶
type UtxoEntry struct {
// contains filtered or unexported fields
}
UtxoEntry houses details about an individual transaction output in a utxo view such as whether or not it was contained in a coinbase tx, the height of the block that contains the tx, whether or not it is spent, its public key script, and how much it pays.
func (*UtxoEntry) BlockHeight ¶
BlockHeight returns the height of the block containing the output.
func (*UtxoEntry) IsCoinBase ¶
IsCoinBase returns whether or not the output was contained in a coinbase transaction.
func (*UtxoEntry) IsSpent ¶
IsSpent returns whether or not the output has been spent based upon the current state of the unspent transaction output view it was obtained from.
type UtxoViewpoint ¶
type UtxoViewpoint struct {
// contains filtered or unexported fields
}
UtxoViewpoint represents a view into the set of unspent transaction outputs from a specific point of view in the chain. For example, it could be for the end of the main chain, some point in the history of the main chain, or down a side chain. The unspent outputs are needed by other transactions for things such as script validation and double spend prevention.
func NewUtxoViewpoint ¶
func NewUtxoViewpoint() *UtxoViewpoint
NewUtxoViewpoint returns a new empty unspent transaction output view.
func (*UtxoViewpoint) AddTxOut ¶
func (view *UtxoViewpoint) AddTxOut(tx *util.Tx, txOutIdx uint32, blockHeight int32)
AddTxOut adds the specified output of the passed transaction to the view if it exists and is not provably unspendable. When the view already has an entry for the output, it will be marked unspent. All fields will be updated for existing entries since it's possible it has changed during a reorg.
func (*UtxoViewpoint) AddTxOuts ¶
func (view *UtxoViewpoint) AddTxOuts(tx *util.Tx, blockHeight int32)
AddTxOuts adds all outputs in the passed transaction which are not provably unspendable to the view. When the view already has entries for any of the outputs, they are simply marked unspent. All fields will be updated for existing entries since it's possible it has changed during a reorg.
func (*UtxoViewpoint) BestHash ¶
func (view *UtxoViewpoint) BestHash() *chainhash.Hash
BestHash returns the hash of the best block in the chain the view currently respresents.
func (*UtxoViewpoint) Entries ¶
func (view *UtxoViewpoint) Entries() map[wire.OutPoint]*UtxoEntry
Entries returns the underlying map that stores of all the utxo entries.
func (*UtxoViewpoint) LookupEntry ¶
func (view *UtxoViewpoint) LookupEntry(outpoint wire.OutPoint) *UtxoEntry
LookupEntry returns information about a given transaction output according to the current state of the view. It will return nil if the passed output does not exist in the view or is otherwise not available such as when it has been disconnected during a reorg.
func (*UtxoViewpoint) RemoveEntry ¶
func (view *UtxoViewpoint) RemoveEntry(outpoint wire.OutPoint)
RemoveEntry removes the given transaction output from the current state of the view. It will have no effect if the passed output does not exist in the view.
func (*UtxoViewpoint) SetBestHash ¶
func (view *UtxoViewpoint) SetBestHash(hash *chainhash.Hash)
SetBestHash sets the hash of the best block in the chain the view currently respresents.
Source Files ¶
- accept.go
- blacklist.go
- blockindex.go
- chain.go
- chainio.go
- chainview.go
- checkpoints.go
- compress.go
- difficulty.go
- doc.go
- error.go
- forkhalcyon.go
- forkplan9.go
- forkplan9controller.go
- forkplan9helpers.go
- mediantime.go
- merkle.go
- notifications.go
- process.go
- scriptval.go
- thresholdstate.go
- timesorter.go
- upgrade.go
- utxoviewpoint.go
- validate.go
- versionbits.go
- weight.go
Directories ¶
Path | Synopsis |
---|---|
Package chaincfg defines chain configuration parameters.
|
Package chaincfg defines chain configuration parameters. |
Package fork handles tracking the hard fork status and is used to determine which consensus rules apply on a block
|
Package fork handles tracking the hard fork status and is used to determine which consensus rules apply on a block |
Package fullblocktests provides a set of block consensus validation tests.
|
Package fullblocktests provides a set of block consensus validation tests. |
Package chainhash provides abstracted hash functionality.
|
Package chainhash provides abstracted hash functionality. |
Package indexers implements optional block chain indexes.
|
Package indexers implements optional block chain indexes. |
Package netsync implements a concurrency safe block syncing protocol.
|
Package netsync implements a concurrency safe block syncing protocol. |
Package wallettx provides ...
|
Package wallettx provides ... |
author
Package txauthor provides transaction creation code for wallets.
|
Package txauthor provides transaction creation code for wallets. |
mgr
Package wtxmgr provides an implementation of a transaction database handling spend tracking for a bitcoin wallet.
|
Package wtxmgr provides an implementation of a transaction database handling spend tracking for a bitcoin wallet. |
rules
Package txrules provides transaction rules that should be followed by transaction authors for wide mempool acceptance and quick mining.
|
Package txrules provides transaction rules that should be followed by transaction authors for wide mempool acceptance and quick mining. |
script
Package txscript implements the bitcoin transaction script language.
|
Package txscript implements the bitcoin transaction script language. |
sort
Package txsort provides the transaction sorting according to BIP 69.
|
Package txsort provides the transaction sorting according to BIP 69. |
Package wire implements the bitcoin wire protocol.
|
Package wire implements the bitcoin wire protocol. |