Documentation ¶
Overview ¶
Package blockchain implements decred block handling and chain selection rules.
The decred block handling and chain selection rules are an integral, and quite likely the most important, part of decred. 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, decred 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 decred 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.
Decred 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 BlockOneCoinbasePaysTokens(tx *dcrutil.Tx, params *chaincfg.Params) error
- func BuildMerkleTreeStore(transactions []*dcrutil.Tx) []*chainhash.Hash
- func CalcBlockTaxSubsidy(height int64, voters uint16, params *chaincfg.Params) int64
- func CalcBlockWorkSubsidy(height int64, voters uint16, params *chaincfg.Params) int64
- func CalcStakeVoteSubsidy(height int64, params *chaincfg.Params) int64
- func CalcWork(bits uint32) *big.Int
- func CheckBlockSanity(block *dcrutil.Block, timeSource MedianTimeSource, ...) error
- func CheckProofOfStake(block *dcrutil.Block, posLimit int64) error
- func CheckProofOfWork(block *dcrutil.Block, powLimit *big.Int) error
- func CheckTransactionInputs(tx *dcrutil.Tx, txHeight int64, txStore TxStore, checkFraudProof bool, ...) (int64, error)
- func CheckTransactionSanity(tx *dcrutil.Tx, params *chaincfg.Params) error
- func CheckWorklessBlockSanity(block *dcrutil.Block, timeSource MedianTimeSource, ...) error
- func CoinbasePaysTax(tx *dcrutil.Tx, height uint32, voters uint16, params *chaincfg.Params) error
- func CompactToBig(compact uint32) *big.Int
- func CountP2SHSigOps(tx *dcrutil.Tx, isCoinBaseTx bool, isStakeBaseTx bool, txStore TxStore) (int, error)
- func CountSigOps(tx *dcrutil.Tx, isCoinBaseTx bool, isSSGen bool) int
- func DebugBlockHeaderString(chainParams *chaincfg.Params, block *dcrutil.Block) string
- func DebugBlockString(block *dcrutil.Block) string
- func DebugMsgTxString(msgTx *wire.MsgTx) string
- func DebugTicketDBLiveBucketString(tmdb *stake.TicketDB, bucket uint8, verbose bool) (string, error)
- func DebugTicketDBLiveString(tmdb *stake.TicketDB, chainParams *chaincfg.Params) (string, error)
- func DebugTicketDBMissedString(tmdb *stake.TicketDB, verbose bool) (string, error)
- func DebugTicketDBSpentBucketString(tmdb *stake.TicketDB, height int64, verbose bool) (string, error)
- func DebugTicketDataString(td *stake.TicketData) string
- func DebugTxStoreData(txs TxStore) string
- func DisableLog()
- func HashMerkleBranches(left *chainhash.Hash, right *chainhash.Hash) *chainhash.Hash
- func IsCoinBase(tx *dcrutil.Tx) bool
- func IsCoinBaseTx(msgTx *wire.MsgTx) bool
- func IsFinalizedTransaction(tx *dcrutil.Tx, blockHeight int64, blockTime time.Time) bool
- func SetLogWriter(w io.Writer, level string) error
- func ShaHashToBig(hash *chainhash.Hash) *big.Int
- func TicketDbThumbprint(tmdb *stake.TicketDB, chainParams *chaincfg.Params) ([]*chainhash.Hash, error)
- func UseLogger(logger btclog.Logger)
- func ValidateTransactionScripts(tx *dcrutil.Tx, txStore TxStore, flags txscript.ScriptFlags) error
- type BehaviorFlags
- type BlockAcceptedNtfnsData
- type BlockChain
- func (b *BlockChain) BlockLocatorFromHash(hash *chainhash.Hash) BlockLocator
- func (b *BlockChain) CalcNextRequiredDiffFromNode(hash *chainhash.Hash, timestamp time.Time) (uint32, error)
- func (b *BlockChain) CalcNextRequiredDifficulty(timestamp time.Time) (uint32, error)
- func (b *BlockChain) CalcNextRequiredStakeDifficulty() (int64, error)
- func (b *BlockChain) CalcPastMedianTime() (time.Time, error)
- func (b *BlockChain) CheckBlockStakeSanity(tixStore TicketStore, stakeValidationHeight int64, node *blockNode, ...) error
- func (b *BlockChain) CheckConnectBlock(block *dcrutil.Block) error
- func (b *BlockChain) CheckLiveTicket(hash *chainhash.Hash) (bool, error)
- func (b *BlockChain) CheckLiveTickets(hashes []*chainhash.Hash) ([]bool, error)
- func (b *BlockChain) Checkpoints() []chaincfg.Checkpoint
- func (b *BlockChain) DisableCheckpoints(disable bool)
- func (b *BlockChain) DisableVerify(disable bool)
- func (b *BlockChain) EstimateNextStakeDifficulty(ticketsInWindow int64, useMaxTickets bool) (int64, error)
- func (b *BlockChain) FetchTransactionStore(tx *dcrutil.Tx, isValid bool) (TxStore, error)
- func (b *BlockChain) ForceHeadReorganization(formerBest chainhash.Hash, newBest chainhash.Hash, timeSource MedianTimeSource) error
- func (b *BlockChain) GenerateInitialIndex() error
- func (b *BlockChain) GenerateLiveTicketBucket(ticketStore TicketStore, tpdBucketMap map[uint8][]*TicketPatchData, ...) (stake.SStxMemMap, error)
- func (b *BlockChain) GenerateMissedTickets(tixStore TicketStore) (stake.SStxMemMap, error)
- func (b *BlockChain) GetBlockFromHash(hash *chainhash.Hash) (*dcrutil.Block, error)
- func (b *BlockChain) GetCurrentBlockHeader() *wire.BlockHeader
- func (b *BlockChain) GetGeneration(hash chainhash.Hash) ([]chainhash.Hash, error)
- func (b *BlockChain) GetMissedTickets() []chainhash.Hash
- func (b *BlockChain) GetNextWinningTickets() ([]chainhash.Hash, int, [6]byte, error)
- func (b *BlockChain) GetOrphanRoot(hash *chainhash.Hash) *chainhash.Hash
- func (b *BlockChain) GetTopBlock() (dcrutil.Block, error)
- func (b *BlockChain) GetWinningTickets(nodeHash chainhash.Hash) ([]chainhash.Hash, int, [6]byte, error)
- func (b *BlockChain) HaveBlock(hash *chainhash.Hash) (bool, error)
- func (b *BlockChain) IsCheckpointCandidate(block *dcrutil.Block) (bool, error)
- func (b *BlockChain) IsCurrent(timeSource MedianTimeSource) bool
- func (b *BlockChain) IsKnownOrphan(hash *chainhash.Hash) bool
- func (b *BlockChain) LatestBlockLocator() (BlockLocator, error)
- func (b *BlockChain) LatestCheckpoint() *chaincfg.Checkpoint
- func (b *BlockChain) LiveTickets() ([]*chainhash.Hash, error)
- func (b *BlockChain) MissedTickets() (stake.SStxMemMap, error)
- func (b *BlockChain) ProcessBlock(block *dcrutil.Block, timeSource MedianTimeSource, flags BehaviorFlags) (bool, bool, error)
- func (b *BlockChain) StakeValidationHeight() int64
- func (b *BlockChain) TicketPoolValue() (dcrutil.Amount, error)
- func (b *BlockChain) TicketsWithAddress(address dcrutil.Address) ([]chainhash.Hash, error)
- type BlockLocator
- type ErrorCode
- type MedianTimeSource
- type Notification
- type NotificationCallback
- type NotificationType
- type ReorganizationNtfnsData
- type RuleError
- type TicketNotificationsData
- type TicketPatchData
- type TicketStatus
- type TicketStore
- type TxData
- type TxStore
Examples ¶
Constants ¶
const ( TiNonexisting = iota TiSpent TiAvailable TiMissed TiRevoked TiError )
Possible values for TicketStatus
const ( // MaxSigOpsPerBlock is the maximum number of signature operations // allowed for a block. It is a fraction of the max block payload size. MaxSigOpsPerBlock = wire.MaxBlockPayload / 200 // 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 CheckpointConfirmations = 4096
CheckpointConfirmations is the number of blocks before the end of the current best block chain that a good checkpoint candidate must be.
const ViewpointPrevInvalidRegular = int8(4)
ViewpointPrevInvalidRegular is the viewpoint from the perspective of the everything up the the previous block's TxTreeRegular minus the contents of the TxTreeRegular and TxTreeStake of current block, to validate TxTreeRegular of the current block.
const ViewpointPrevInvalidStake = int8(2)
ViewpointPrevInvalidStake is the viewpoint from the perspective of the everything up the the previous block's TxTreeRegular but without the contents of the TxTreeRegular, to validate TxTreeStake.
const ViewpointPrevValidInitial = int8(0)
ViewpointPrevValidInitial is the viewpoint from the perspective of the everything up the the previous block's TxTreeRegular, used to validate that tx tree regular.
const ViewpointPrevValidRegular = int8(3)
ViewpointPrevValidRegular is the viewpoint from the perspective of the everything up the the previous block's TxTreeRegular plus the contents of the TxTreeRegular and TxTreeStake of current block, to validate TxTreeRegular of the current block.
const ViewpointPrevValidStake = int8(1)
ViewpointPrevValidStake is the viewpoint from the perspective of the everything up the the previous block's TxTreeRegular plus the contents of the TxTreeRegular, to validate TxTreeStake.
Variables ¶
var ErrIndexAlreadyInitialized = errors.New("the block index can only be " +
"initialized before it has been modified")
ErrIndexAlreadyInitialized describes an error that indicates the block index is already initialized.
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/decred/dcrd/blockchain" _ "github.com/decred/dcrd/database/memdb" ) 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 BlockOneCoinbasePaysTokens ¶
BlockOneCoinbasePaysTokens checks to see if the first block coinbase pays out to the network initial token ledger.
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 decred 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.
func CalcBlockTaxSubsidy ¶
CalcBlockTaxSubsidy calculates the subsidy for the organization address in the coinbase.
Safe for concurrent access.
func CalcBlockWorkSubsidy ¶
CalcBlockWorkSubsidy calculates the proof of work subsidy for a block as a proportion of the total subsidy.
func CalcStakeVoteSubsidy ¶
CalcStakeVoteSubsidy calculates the subsidy for a stake vote based on the height of its input SStx.
Safe for concurrent access.
func CalcWork ¶
CalcWork calculates a work value from difficulty bits. Decred 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 documenation 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 *dcrutil.Block, timeSource MedianTimeSource, chainParams *chaincfg.Params) 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 CheckProofOfStake ¶
CheckProofOfStake exports the above func.
func 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 CheckTransactionInputs ¶
func CheckTransactionInputs(tx *dcrutil.Tx, txHeight int64, txStore TxStore, checkFraudProof bool, chainParams *chaincfg.Params) (int64, 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 decred and therefore allowed to spend them. As it checks the inputs, it also calculates the total fees for the transaction and returns that value.
func CheckTransactionSanity ¶
CheckTransactionSanity performs some preliminary checks on a transaction to ensure it is sane. These checks are context free.
func CheckWorklessBlockSanity ¶
func CheckWorklessBlockSanity(block *dcrutil.Block, timeSource MedianTimeSource, chainParams *chaincfg.Params) error
CheckWorklessBlockSanity performs some preliminary checks on a block to ensure it is sane before continuing with block processing. These checks are context free.
func CoinbasePaysTax ¶
CoinbasePaysTax checks to see if a given block's coinbase correctly pays tax to the developer organization.
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 decred 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/decred/dcrd/blockchain" _ "github.com/decred/dcrd/database/memdb" ) func main() { // Convert the bits from block 300000 in the main Decred block chain. bits := uint32(419465580) targetDifficulty := blockchain.CompactToBig(bits) // Display it in hex. fmt.Printf("%064x\n", targetDifficulty.Bytes()) }
Output: 0000000000000000896c00000000000000000000000000000000000000000000
func CountP2SHSigOps ¶
func CountP2SHSigOps(tx *dcrutil.Tx, isCoinBaseTx bool, isStakeBaseTx bool, txStore TxStore) (int, error)
CountP2SHSigOps returns the number of signature operations for all input transactions which are of the pay-to-script-hash type. This uses the precise, signature operation counting mechanism from the script engine which requires access to the input transaction scripts.
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 DebugBlockHeaderString ¶
DebugBlockHeaderString dumps a verbose message containing information about the block header of a block.
func DebugBlockString ¶
DebugBlockString dumps a verbose message containing information about the transactions of a block.
func DebugMsgTxString ¶
DebugMsgTxString dumps a verbose message containing information about the contents of a transaction.
func DebugTicketDBLiveBucketString ¶
func DebugTicketDBLiveBucketString(tmdb *stake.TicketDB, bucket uint8, verbose bool) (string, error)
DebugTicketDBLiveBucketString returns a string containing the ticket hashes found in a specific bucket of the live ticket database. If the verbose flag is called, it dumps the contents of the ticket data as well.
func DebugTicketDBLiveString ¶
DebugTicketDBLiveString prints out the number of tickets in each bucket of the ticket database as a string.
func DebugTicketDBMissedString ¶
DebugTicketDBMissedString prints out the contents of the missed ticket database to a string. If verbose is indicated, the ticket data itself is printed along with the ticket hashes.
func DebugTicketDBSpentBucketString ¶
func DebugTicketDBSpentBucketString(tmdb *stake.TicketDB, height int64, verbose bool) (string, error)
DebugTicketDBSpentBucketString prints the contents of the spent tickets database bucket indicated to a string that is returned. If the verbose flag is indicated, the contents of each ticket are printed as well.
func DebugTicketDataString ¶
func DebugTicketDataString(td *stake.TicketData) string
DebugTicketDataString writes the contents of a ticket data struct as a string.
func DebugTxStoreData ¶
DebugTxStoreData returns a string containing information about the data stored in the given TxStore.
func DisableLog ¶
func DisableLog()
DisableLog disables all library log output. Logging output is disabled by default until either UseLogger or SetLogWriter are called.
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 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 IsFinalizedTransaction ¶
IsFinalizedTransaction determines whether or not a transaction is finalized.
func SetLogWriter ¶
SetLogWriter uses a specified io.Writer to output package logging info. This allows a caller to direct package logging output without needing a dependency on seelog. If the caller is also using btclog, UseLogger should be used instead.
func ShaHashToBig ¶
ShaHashToBig converts a wire.ShaHash into a big.Int that can be used to perform math comparisons.
func TicketDbThumbprint ¶
func TicketDbThumbprint(tmdb *stake.TicketDB, chainParams *chaincfg.Params) ([]*chainhash.Hash, error)
TicketDbThumbprint takes all the tickets in the respective ticket db, sorts them, hashes their contents into a list, and then hashes that list. The resultant hash is the thumbprint of the ticket database, and should be the same across all clients that are synced to the same block. Returns an array of hashes len 3, containing (1) live tickets (2) spent tickets and (3) missed tickets. Do NOT use on mainnet or in production. For debug use only! Make sure the blockchain is frozen when you call this function.
func UseLogger ¶
UseLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using btclog.
func ValidateTransactionScripts ¶
ValidateTransactionScripts validates the scripts for the passed transaction using multiple goroutines.
Types ¶
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 // BFDryRun may be set to indicate the block should not modify the chain // or memory chain index. This is useful to test that a block is valid // without modifying the current state. BFDryRun // BFNone is a convenience value to specifically indicate no flags. BFNone BehaviorFlags = 0 )
type BlockAcceptedNtfnsData ¶
BlockAcceptedNtfnsData is the structure for data indicating information about a block being accepted.
type BlockChain ¶
type BlockChain struct {
// contains filtered or unexported fields
}
BlockChain provides functions for working with the decred 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(db database.Db, tmdb *stake.TicketDB, params *chaincfg.Params, c NotificationCallback) *BlockChain
New returns a BlockChain instance for the passed decred network using the provided backing database. It accepts a callback on which notifications will be sent when various events take place. See the documentation for Notification and NotificationType for details on the types and contents of notifications. The provided callback can be nil if the caller is not interested in receiving notifications.
func (*BlockChain) BlockLocatorFromHash ¶
func (b *BlockChain) BlockLocatorFromHash(hash *chainhash.Hash) BlockLocator
BlockLocatorFromHash returns a block locator for the passed block hash. See BlockLocator for details on the algotirhm used to create a block locator.
In addition to the general algorithm referenced above, there are a couple of special cases which are handled:
- If the genesis hash is passed, there are no previous hashes to add and therefore the block locator will only consist of the genesis hash
- If the passed hash is not currently known, the block locator will only consist of the passed hash
func (*BlockChain) CalcNextRequiredDiffFromNode ¶
func (b *BlockChain) CalcNextRequiredDiffFromNode(hash *chainhash.Hash, timestamp time.Time) (uint32, error)
CalcNextRequiredDiffFromNode calculates the required difficulty for the block given with the passed hash along with the given timestamp.
This function is NOT safe for concurrent access.
func (*BlockChain) CalcNextRequiredDifficulty ¶
func (b *BlockChain) CalcNextRequiredDifficulty(timestamp time.Time) (uint32, error)
CalcNextRequiredDifficulty calculates the required difficulty for the block after the end of the current best chain based on the difficulty retarget rules.
This function is NOT safe for concurrent access.
func (*BlockChain) CalcNextRequiredStakeDifficulty ¶
func (b *BlockChain) CalcNextRequiredStakeDifficulty() (int64, error)
CalcNextRequiredStakeDifficulty is the exported version of the above function. This function is NOT safe for concurrent access.
func (*BlockChain) CalcPastMedianTime ¶
func (b *BlockChain) CalcPastMedianTime() (time.Time, error)
CalcPastMedianTime calculates the median time of the previous few blocks prior to, and including, the end of the current best chain. It is primarily used to ensure new blocks have sane timestamps.
This function is NOT safe for concurrent access.
func (*BlockChain) CheckBlockStakeSanity ¶
func (b *BlockChain) CheckBlockStakeSanity(tixStore TicketStore, stakeValidationHeight int64, node *blockNode, block *dcrutil.Block, parent *dcrutil.Block, chainParams *chaincfg.Params) error
CheckBlockStakeSanity performs a series of checks on a block to ensure that the information from the block's header about stake is sane. For instance, the number of SSGen tx must be equal to voters. TODO: We can consider breaking this into two functions and making some of these checks go through in processBlock, however if a block has demonstrable PoW it seems unlikely that it will have stake errors (because the miner is then just wasting hash power).
func (*BlockChain) CheckConnectBlock ¶
func (b *BlockChain) CheckConnectBlock(block *dcrutil.Block) error
CheckConnectBlock performs several checks to confirm connecting the passed block to the main chain does not violate any rules. An example of some of the checks performed are ensuring connecting the block would not cause any duplicate transaction hashes for old transactions that aren't already fully spent, double spends, exceeding the maximum allowed signature operations per block, invalid values in relation to the expected block subsidy, or fail transaction script validation.
This function is NOT safe for concurrent access.
func (*BlockChain) CheckLiveTicket ¶ added in v0.0.4
func (b *BlockChain) CheckLiveTicket(hash *chainhash.Hash) (bool, error)
CheckLiveTicket returns whether or not a ticket exists in the live ticket map of the stake database.
This function is NOT safe for concurrent access.
func (*BlockChain) CheckLiveTickets ¶ added in v0.0.4
func (b *BlockChain) CheckLiveTickets(hashes []*chainhash.Hash) ([]bool, error)
CheckLiveTickets returns whether or not a slice of tickets exist in the live ticket map of the stake database.
This function is NOT safe for concurrent access.
func (*BlockChain) Checkpoints ¶
func (b *BlockChain) Checkpoints() []chaincfg.Checkpoint
Checkpoints returns a slice of checkpoints (regardless of whether they are already known). When checkpoints are disabled or there are no checkpoints for the active network, it will return nil.
func (*BlockChain) DisableCheckpoints ¶
func (b *BlockChain) DisableCheckpoints(disable bool)
DisableCheckpoints provides a mechanism to disable validation against checkpoints which you DO NOT want to do in production. It is provided only for debug purposes.
func (*BlockChain) DisableVerify ¶
func (b *BlockChain) DisableVerify(disable bool)
DisableVerify provides a mechanism to disable transaction script validation which you DO NOT want to do in production as it could allow double spends and othe undesirable things. It is provided only for debug purposes since script validation is extremely intensive and when debugging it is sometimes nice to quickly get the chain.
func (*BlockChain) EstimateNextStakeDifficulty ¶ added in v0.1.2
func (b *BlockChain) EstimateNextStakeDifficulty(ticketsInWindow int64, useMaxTickets bool) (int64, error)
EstimateNextStakeDifficulty is the exported version of the above function. This function is NOT safe for concurrent access.
func (*BlockChain) FetchTransactionStore ¶
FetchTransactionStore fetches the input transactions referenced by the passed transaction from the point of view of the end of the main chain. It also attempts to fetch the transaction itself so the returned TxStore can be examined for duplicate transactions. IsValid indicates if the current block on head has had its TxTreeRegular validated by the stake voters.
func (*BlockChain) ForceHeadReorganization ¶
func (b *BlockChain) ForceHeadReorganization(formerBest chainhash.Hash, newBest chainhash.Hash, timeSource MedianTimeSource) error
ForceHeadReorganization is the exported version of forceHeadReorganization.
func (*BlockChain) GenerateInitialIndex ¶
func (b *BlockChain) GenerateInitialIndex() error
GenerateInitialIndex is an optional function which generates the required number of initial block nodes in an optimized fashion. This is optional because the memory block index is sparse and previous nodes are dynamically loaded as needed. However, during initial startup (when there are no nodes in memory yet), dynamically loading all of the required nodes on the fly in the usual way is much slower than preloading them.
This function can only be called once and it must be called before any nodes are added to the block index. ErrIndexAlreadyInitialized is returned if the former is not the case. In practice, this means the function should be called directly after New.
func (*BlockChain) GenerateLiveTicketBucket ¶
func (b *BlockChain) GenerateLiveTicketBucket(ticketStore TicketStore, tpdBucketMap map[uint8][]*TicketPatchData, bucket uint8) (stake.SStxMemMap, error)
GenerateLiveTicketBucket takes ticket patch data and a bucket number as input, then recreates a ticket bucket from the patch and the current database state.
func (*BlockChain) GenerateMissedTickets ¶
func (b *BlockChain) GenerateMissedTickets(tixStore TicketStore) (stake.SStxMemMap, error)
GenerateMissedTickets takes ticket patch data as input, then recreates the missed tickets bucket from the patch and the current database state.
func (*BlockChain) GetBlockFromHash ¶
GetBlockFromHash is the generalized and exported version of getBlockFromHash.
func (*BlockChain) GetCurrentBlockHeader ¶
func (b *BlockChain) GetCurrentBlockHeader() *wire.BlockHeader
GetCurrentBlockHeader returns the block header of the block at HEAD. This function is NOT safe for concurrent access.
func (*BlockChain) GetGeneration ¶
GetGeneration is the exported version of getGeneration.
func (*BlockChain) GetMissedTickets ¶
func (b *BlockChain) GetMissedTickets() []chainhash.Hash
GetMissedTickets returns a list of currently missed tickets. This function is NOT safe for concurrent access.
func (*BlockChain) GetNextWinningTickets ¶
GetNextWinningTickets returns the next tickets eligible for spending as SSGen on the top block. It also returns the ticket pool size. This function is NOT safe for concurrent access.
func (*BlockChain) GetOrphanRoot ¶
func (b *BlockChain) GetOrphanRoot(hash *chainhash.Hash) *chainhash.Hash
GetOrphanRoot returns the head of the chain for the provided hash from the map of orphan blocks.
This function is safe for concurrent access.
func (*BlockChain) GetTopBlock ¶
func (b *BlockChain) GetTopBlock() (dcrutil.Block, error)
GetTopBlock returns the current block at HEAD on the blockchain. Needed for mining in the daemon.
func (*BlockChain) GetWinningTickets ¶
func (b *BlockChain) GetWinningTickets(nodeHash chainhash.Hash) ([]chainhash.Hash, int, [6]byte, error)
GetWinningTickets takes a node block hash and returns the next tickets eligible for spending as SSGen. This function is NOT safe for concurrent access.
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 NOT safe for concurrent access.
func (*BlockChain) IsCheckpointCandidate ¶
func (b *BlockChain) IsCheckpointCandidate(block *dcrutil.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.
func (*BlockChain) IsCurrent ¶
func (b *BlockChain) IsCurrent(timeSource MedianTimeSource) 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 NOT safe for concurrent access.
func (*BlockChain) IsKnownOrphan ¶
func (b *BlockChain) IsKnownOrphan(hash *chainhash.Hash) bool
IsKnownOrphan returns whether the passed hash is currently a known orphan. Keep in mind that only a limited number of orphans are held onto for a limited amount of time, so this function must not be used as an absolute way to test if a block is an orphan block. A full block (as opposed to just its hash) must be passed to ProcessBlock for that purpose. However, calling ProcessBlock with an orphan that already exists results in an error, so this function provides a mechanism for a caller to intelligently detect *recent* duplicate orphans and react accordingly.
This function is safe for concurrent access.
func (*BlockChain) LatestBlockLocator ¶
func (b *BlockChain) LatestBlockLocator() (BlockLocator, error)
LatestBlockLocator returns a block locator for the latest known tip of the main (best) chain.
func (*BlockChain) LatestCheckpoint ¶
func (b *BlockChain) LatestCheckpoint() *chaincfg.Checkpoint
LatestCheckpoint returns the most recent checkpoint (regardless of whether it is already known). When checkpoints are disabled or there are no checkpoints for the active network, it will return nil.
func (*BlockChain) LiveTickets ¶ added in v0.0.10
func (b *BlockChain) LiveTickets() ([]*chainhash.Hash, error)
LiveTickets returns all currently live tickets from the stake database.
This function is NOT safe for concurrent access.
func (*BlockChain) MissedTickets ¶
func (b *BlockChain) MissedTickets() (stake.SStxMemMap, error)
MissedTickets returns all currently missed tickets from the stake database.
This function is NOT safe for concurrent access.
func (*BlockChain) ProcessBlock ¶
func (b *BlockChain) ProcessBlock(block *dcrutil.Block, timeSource MedianTimeSource, flags BehaviorFlags) (bool, bool, error)
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.
It returns a first bool specifying whether or not the block is on on a fork or on a side chain. True means it's on the main chain.
It returns a second bool which indicates whether or not the block is an orphan and any errors that occurred during processing. The returned bool is only valid when the error is nil.
Example ¶
This example demonstrates how to create a new chain instance and use ProcessBlock to attempt to attempt add a block to the chain. As the package overview documentation describes, this includes all of the Decred consensus rules. This example intentionally attempts to insert a duplicate genesis block to illustrate how an invalid block is handled.
package main import ( "fmt" "github.com/decred/dcrd/blockchain" "github.com/decred/dcrd/blockchain/stake" "github.com/decred/dcrd/chaincfg" "github.com/decred/dcrd/database" "github.com/decred/dcrutil" _ "github.com/decred/dcrd/database/memdb" ) func main() { // Create a new database to store the accepted blocks into. Typically // this would be opening an existing database and would not use memdb // which is a memory-only database backend, but we create a new db // here so this is a complete working example. db, err := database.CreateDB("memdb") if err != nil { fmt.Printf("Failed to create database: %v\n", err) return } defer db.Close() var tmdb *stake.TicketDB // Insert the main network genesis block. This is part of the initial // database setup. Like above, this typically would not be needed when // opening an existing database. genesisBlock := dcrutil.NewBlock(chaincfg.MainNetParams.GenesisBlock) _, err = db.InsertBlock(genesisBlock) if err != nil { fmt.Printf("Failed to insert genesis block: %v\n", err) return } // Create a new BlockChain instance using the underlying database for // the main decred network and ignore notifications. chain := blockchain.New(db, tmdb, &chaincfg.MainNetParams, nil) // Create a new median time source that is required by the upcoming // call to ProcessBlock. Ordinarily this would also add time values // obtained from other peers on the network so the local time is // adjusted to be in agreement with other peers. timeSource := blockchain.NewMedianTime() // Process a block. For this example, we are going to intentionally // cause an error by trying to process the genesis block which already // exists. isOrphan, _, err := chain.ProcessBlock(genesisBlock, timeSource, blockchain.BFNone) if err != nil { fmt.Printf("Failed to process block: %v\n", err) return } fmt.Printf("Block accepted. Is it an orphan?: %v", isOrphan) // This output is dependent on the genesis block, and needs to be // updated if the mainnet genesis block is updated.
Output:
func (*BlockChain) StakeValidationHeight ¶
func (b *BlockChain) StakeValidationHeight() int64
StakeValidationHeight returns the height at which proof of stake validation begins for proof of work block headers.
func (*BlockChain) TicketPoolValue ¶ added in v0.0.8
func (b *BlockChain) TicketPoolValue() (dcrutil.Amount, error)
TicketPoolValue returns the current value of all the locked funds in the ticket pool.
This function is NOT safe for concurrent access.
func (*BlockChain) TicketsWithAddress ¶
TicketsWithAddress returns a slice of ticket hashes that are currently live corresponding to the given address.
This function is NOT safe for concurrent access.
type BlockLocator ¶
BlockLocator is used to help locate a specific block. The algorithm for building the block locator is to add the hashes in reverse order until the genesis block is reached. In order to keep the list of locator hashes to a reasonable number of entries, first the most recent previous 10 block hashes are added, then the step is doubled each loop iteration to exponentially decrease the number of hashes as a function of the distance from the block being located.
For example, assume you have a block chain with a side chain as depicted below:
genesis -> 1 -> 2 -> ... -> 15 -> 16 -> 17 -> 18 \-> 16a -> 17a
The block locator for block 17a would be the hashes of blocks: [17a 16a 15 14 13 12 11 10 9 8 6 2 genesis]
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 // ErrMissingParent indicates that the block was an orphan. ErrMissingParent // ErrBlockTooBig indicates the serialized block size exceeds the // maximum allowed size. ErrBlockTooBig // ErrWrongBlockSize indicates that the block size from the header was // not the actual serialized size of the block. ErrWrongBlockSize // 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 // ErrTooManyTransactions indicates the block has more transactions than // are allowed. ErrTooManyTransactions // 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 // ErrMissingTx indicates a transaction referenced by an input is // missing. ErrMissingTx // 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 // ErrDoubleSpend indicates a transaction is attempting to spend coins // that have already been spent. ErrDoubleSpend // 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 // ErrCoinbaseHeight indicates that the encoded height in the coinbase // is incorrect. ErrCoinbaseHeight // ErrMultipleCoinbases indicates a block contains more than one // coinbase transaction. ErrMultipleCoinbases // ErrStakeTxInRegularTree indicates a stake transaction was found in // the regular transaction tree. ErrStakeTxInRegularTree // ErrRegTxInStakeTree indicates that a regular transaction was found in // the stake transaction tree. ErrRegTxInStakeTree // 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 // ErrBadCoinbaseOutpoint indicates that the outpoint used by a coinbase // as input was non-null. ErrBadCoinbaseOutpoint // ErrBadCoinbaseFraudProof indicates that the fraud proof for a coinbase // input was non-null. ErrBadCoinbaseFraudProof // ErrBadCoinbaseAmountIn indicates that the AmountIn (=subsidy) for a // coinbase input was incorrect. ErrBadCoinbaseAmountIn // ErrBadStakebaseAmountIn indicates that the AmountIn (=subsidy) for a // stakebase input was incorrect. ErrBadStakebaseAmountIn // ErrBadStakebaseScriptLen indicates the length of the signature script // for a stakebase transaction is not within the valid range. ErrBadStakebaseScriptLen // ErrBadStakevaseScrVal indicates the signature script for a stakebase // transaction was not set to the network consensus value. ErrBadStakevaseScrVal // 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 // ErrNotEnoughStake indicates that there was for some SStx in a given block, // the given SStx did not have enough stake to meet the network target. ErrNotEnoughStake // ErrStakeBelowMinimum indicates that for some SStx in a given block, // the given SStx had an amount of stake below the minimum network target. ErrStakeBelowMinimum // ErrNonstandardStakeTx indicates that a block contained a stake tx that // was not one of the allowed types of a stake transactions. ErrNonstandardStakeTx // ErrNotEnoughVotes indicates that a block contained less than a majority // of voters. ErrNotEnoughVotes // ErrTooManyVotes indicates that a block contained more than the maximum // allowable number of votes. ErrTooManyVotes // ErrFreshStakeMismatch indicates that a block's header contained a different // number of SStx as compared to what was found in the block. ErrFreshStakeMismatch // ErrTooManySStxs indicates that more than the allowed number of SStx was // found in a block. ErrTooManySStxs // ErrInvalidEarlyStakeTx indicates that a tx type other than SStx was found // in the stake tx tree before the period when stake validation begins, or // before the stake tx type could possibly be included in the block. ErrInvalidEarlyStakeTx // that could not be found. ErrTicketUnavailable // ErrVotesOnWrongBlock indicates that an SSGen voted on a block not the // block's parent, and so was ineligible for inclusion into that block. ErrVotesOnWrongBlock // ErrVotesMismatch indicates that the number of SSGen in the block was not // equivalent to the number of votes provided in the block header. ErrVotesMismatch // ErrIncongruentVotebit indicates that the first votebit in votebits was not // the same as that determined by the majority of voters in the SSGen tx // included in the block. ErrIncongruentVotebit // ErrInvalidSSRtx indicates than an SSRtx in a block could not be found to // have a valid missed sstx input as per the stake ticket database. ErrInvalidSSRtx // ErrInvalidRevNum indicates that the number of revocations from the // header was not the same as the number of SSRtx included in the block. ErrInvalidRevNum // ErrTooManyRevocations indicates more revocations were found in a block // than were allowed. ErrTooManyRevocations // ErrSStxCommitment indicates that the propotional amounts from the inputs // of an SStx did not match those found in the commitment outputs. ErrSStxCommitment // ErrUnparseableSSGen indicates that the SSGen block vote or votebits data // was unparseable from the null data outputs. ErrUnparseableSSGen // ErrInvalidSSGenInput indicates that the input SStx to the SSGen tx was // invalid because it was not an SStx. ErrInvalidSSGenInput // ErrSSGenPayeeNum indicates that the number of payees from the referenced // SSGen's SStx was not the same as the number of the payees in the outputs // of the SSGen tx. ErrSSGenPayeeNum // ErrSSGenPayeeOuts indicates that the SSGen payee outputs were either not // the values that would be expected given the rewards and input amounts of // the original SStx, or that the SSGen addresses did not correctly correspond // to the null data outputs given in the originating SStx. ErrSSGenPayeeOuts // ErrSSGenSubsidy indicates that there was an error in the amount of subsidy // generated in the vote. ErrSSGenSubsidy // ErrSStxInImmature indicates that the OP_SSTX tagged output used as input // was not yet TicketMaturity many blocks old. ErrSStxInImmature // ErrSStxInScrType indicates that the input used in an sstx was not // pay-to-pubkeyhash or pay-to-script-hash, which is required. It can // be OP_SS* tagged, but it must be P2PKH or P2SH. ErrSStxInScrType // ErrInvalidSSRtxInput indicates that the input for the SSRtx was not from // an SStx. ErrInvalidSSRtxInput // ErrSSRtxPayeesMismatch means that the number of payees in an SSRtx was // not the same as the number of payees in the outputs of the input SStx. ErrSSRtxPayeesMismatch // ErrSSRtxPayees indicates that the SSRtx failed to pay out to the committed // addresses or amounts from the originating SStx. ErrSSRtxPayees // ErrTxSStxOutSpend indicates that a non SSGen or SSRtx tx attempted to spend // an OP_SSTX tagged output from an SStx. ErrTxSStxOutSpend // ErrRegTxSpendStakeOut indicates that a regular tx attempted to spend to // outputs tagged with stake tags, e.g. OP_SSTX. ErrRegTxSpendStakeOut // ErrBIP0030 indicates that a block failed to pass BIP0030. ErrBIP0030 // ErrInvalidFinalState indicates that the final state of the PRNG included // in the the block differed from the calculated final state. ErrInvalidFinalState // ErrPoolSize indicates an error in the ticket pool size for this block. ErrPoolSize // ErrForceReorgWrongChain indicates that a reroganization was attempted // to be forced, but the chain indicated was not mirrored by b.bestChain. ErrForceReorgWrongChain // ErrForceReorgMissingChild indicates that a reroganization was attempted // to be forced, but the child node to reorganize to could not be found. ErrForceReorgMissingChild // ErrBadStakebaseValue indicates that a block's stake tx tree has spent // more than it is allowed. ErrBadStakebaseValue // ErrDiscordantTxTree specifies that a given origin tx's content // indicated that it should exist in a different tx tree than the // one given in the TxIn outpoint. ErrDiscordantTxTree // ErrStakeFees indicates an error with the fees found in the stake // transaction tree. ErrStakeFees // ErrNoStakeTx indicates there were no stake transactions found in a // block after stake validation height. ErrNoStakeTx // ErrBadBlockHeight indicates that a block header's embedded block height // was different from where it was actually embedded in the block chain. ErrBadBlockHeight // ErrBlockOneTx indicates that block height 1 failed to correct generate // the block one premine transaction. ErrBlockOneTx // ErrBlockOneTx indicates that block height 1 coinbase transaction in // zero was incorrect in some way. ErrBlockOneInputs // ErrBlockOneOutputs indicates that block height 1 failed to incorporate // the ledger addresses correctly into the transaction's outputs. ErrBlockOneOutputs // ErrNoTax indicates that there was no tax present in the coinbase of a // block after height 1. ErrNoTax // ErrExpiredTx indicates that the transaction is currently expired. ErrExpiredTx // ErrExpiryTxSpentEarly indicates that an output from a transaction // that included an expiry field was spent before coinbase maturity // many blocks had passed in the blockchain. ErrExpiryTxSpentEarly // ErrFraudAmountIn indicates the witness amount given was fraudulent. ErrFraudAmountIn // ErrFraudBlockHeight indicates the witness block height given was fraudulent. ErrFraudBlockHeight // ErrFraudBlockIndex indicates the witness block index given was fraudulent. ErrFraudBlockIndex // ErrZeroValueOutputSpend indicates that a transaction attempted to spend a // zero value output. ErrZeroValueOutputSpend // ErrInvalidEarlyVoteBits indicates that a block before stake validation // height had an unallowed vote bits value. ErrInvalidEarlyVoteBits )
These constants are used to identify a specific RuleError.
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 }
MedianTimeSource provides a mechanism to add several time samples which are used to determine a median time which is then used as an offset to the local clock.
func NewMedianTime ¶
func NewMedianTime() MedianTimeSource
NewMedianTime returns a new instance of concurrency-safe implementation of the MedianTimeSource interface. The returned implementation contains the rules necessary for proper time handling in the chain consensus rules and expects the time samples to be added from the timestamp field of the version message received from remote peers that successfully connect and negotiate.
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: *BlockAcceptedNtfnsData
- NTBlockConnected: []*dcrutil.Block of len 2
- NTBlockDisconnected: []*dcrutil.Block of len 2
- NTReorganization: *ReorganizationNtfnsData
- NTSpentAndMissedTickets: *TicketNotificationsData
- NTNewTickets: *TicketNotificationsData
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 // NTReorganization indicates that a blockchain reorganization is in // progress. NTReorganization // NTSpentAndMissedTickets indicates spent or missed tickets from a newly // accepted block. NTSpentAndMissedTickets // NTSpentAndMissedTickets indicates newly maturing tickets from a newly // accepted block. NTNewTickets )
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 ReorganizationNtfnsData ¶
type ReorganizationNtfnsData struct { OldHash chainhash.Hash OldHeight int64 NewHash chainhash.Hash NewHeight int64 }
ReorganizationNtfnsData is the structure for data indicating information about a reorganization.
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 TicketNotificationsData ¶
type TicketNotificationsData struct { Hash chainhash.Hash Height int64 StakeDifficulty int64 TicketMap stake.SStxMemMap }
TicketNotificationsData is the structure for new/spent/missed ticket notifications at blockchain HEAD that are outgoing from chain.
type TicketPatchData ¶
type TicketPatchData struct {
// contains filtered or unexported fields
}
TicketPatchData contains contextual information about tickets, namely their ticket data and whether or not they are spent.
func NewTicketPatchData ¶
func NewTicketPatchData(td *stake.TicketData, ts TicketStatus, err error) *TicketPatchData
NewTicketPatchData creates a new TicketPatchData struct.
type TicketStatus ¶
type TicketStatus int
TicketStatus is used to indicate the state of a ticket in the ticket store and the ticket database. Non-existing is included because it's possible to have a ticket not exist in a sidechain that exists in the mainchain (and thus exists in the ticket database), and so you need to indicate this in the ticket store. It could also point to a ticket that's been missed and eliminated from the ticket db by SSRtx.
type TicketStore ¶
type TicketStore map[chainhash.Hash]*TicketPatchData
TicketStore is used to store a patch of the ticket db for use in validating the block header and subsequently the block reward. It allows you to observe the ticket db from the point-of-view of different points in the chain. TicketStore is basically like an extremely inefficient version of the ticket database that isn't designed to be able to be easily rolled back, which is fine because we're only going to use it in ephermal cases.
type TxData ¶
type TxData struct { Tx *dcrutil.Tx Hash *chainhash.Hash BlockHeight int64 BlockIndex uint32 Spent []bool Err error }
TxData contains contextual information about transactions such as which block they were found in and whether or not the outputs are spent.
type TxStore ¶
TxStore is used to store transactions needed by other transactions for things such as script validation and double spend prevention. This also allows the transaction data to be treated as a view since it can contain the information from the point-of-view of different points in the chain.