dcrd/blockchain/error.go
2021-09-16 11:10:08 -05:00

780 lines
32 KiB
Go

// Copyright (c) 2014-2016 The btcsuite developers
// Copyright (c) 2015-2021 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package blockchain
import (
"errors"
"fmt"
"strconv"
"strings"
"github.com/decred/dcrd/chaincfg/chainhash"
)
// AssertError identifies an error that indicates an internal code consistency
// issue and should be treated as a critical and unrecoverable error.
type AssertError string
// Error returns the assertion error as a human-readable string and satisfies
// the error interface.
func (e AssertError) Error() string {
return "assertion failed: " + string(e)
}
// ErrorKind identifies a kind of error. It has full support for errors.Is and
// errors.As, so the caller can directly check against an error kind when
// determining the reason for an error.
type ErrorKind string
// These constants are used to identify a specific ErrorKind.
const (
// ErrDuplicateBlock indicates a block with the same hash already
// exists.
ErrDuplicateBlock = ErrorKind("ErrDuplicateBlock")
// ErrMissingParent indicates that the block was an orphan.
ErrMissingParent = ErrorKind("ErrMissingParent")
// ErrNoBlockData indicates an attempt to perform an operation on a block
// that requires all data to be available does not have the data. This is
// typically because the header is known, but the full data has not been
// received yet.
ErrNoBlockData = ErrorKind("ErrNoBlockData")
// ErrBlockTooBig indicates the serialized block size exceeds the
// maximum allowed size.
ErrBlockTooBig = ErrorKind("ErrBlockTooBig")
// ErrWrongBlockSize indicates that the block size in the header is not
// the actual serialized size of the block.
ErrWrongBlockSize = ErrorKind("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 = ErrorKind("ErrBlockVersionTooOld")
// ErrBadStakeVersionindicates the block version is too old and is no
// longer accepted since the majority of the network has upgraded to a
// newer version.
ErrBadStakeVersion = ErrorKind("ErrBadStakeVersion")
// 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 = ErrorKind("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 = ErrorKind("ErrTimeTooOld")
// ErrTimeTooNew indicates the time is too far in the future as compared
// the current time.
ErrTimeTooNew = ErrorKind("ErrTimeTooNew")
// ErrDifficultyTooLow indicates the difficulty for the block is lower
// than the difficulty required by the most recent checkpoint.
ErrDifficultyTooLow = ErrorKind("ErrDifficultyTooLow")
// ErrUnexpectedDifficulty indicates specified bits do not align with
// the expected value either because it doesn't match the calculated
// value based on difficulty regarding the rules or it is out of the
// valid range.
ErrUnexpectedDifficulty = ErrorKind("ErrUnexpectedDifficulty")
// ErrHighHash indicates the block does not hash to a value which is
// lower than the required target difficultly.
ErrHighHash = ErrorKind("ErrHighHash")
// ErrBadMerkleRoot indicates the calculated merkle root does not match
// the expected value.
ErrBadMerkleRoot = ErrorKind("ErrBadMerkleRoot")
// ErrBadCommitmentRoot indicates the calculated commitment root does
// not match the expected value.
ErrBadCommitmentRoot = ErrorKind("ErrBadCommitmentRoot")
// ErrBadCheckpoint indicates a block that is expected to be at a
// checkpoint height does not match the expected one.
ErrBadCheckpoint = ErrorKind("ErrBadCheckpoint")
// ErrForkTooOld indicates a block is attempting to fork the block chain
// before the most recent checkpoint.
ErrForkTooOld = ErrorKind("ErrForkTooOld")
// ErrCheckpointTimeTooOld indicates a block has a timestamp before the
// most recent checkpoint.
ErrCheckpointTimeTooOld = ErrorKind("ErrCheckpointTimeTooOld")
// ErrNoTransactions indicates the block does not have a least one
// transaction. A valid block must have at least the coinbase
// transaction.
ErrNoTransactions = ErrorKind("ErrNoTransactions")
// ErrTooManyTransactions indicates the block has more transactions than
// are allowed.
ErrTooManyTransactions = ErrorKind("ErrTooManyTransactions")
// ErrNoTxInputs indicates a transaction does not have any inputs. A
// valid transaction must have at least one input.
ErrNoTxInputs = ErrorKind("ErrNoTxInputs")
// ErrNoTxOutputs indicates a transaction does not have any outputs. A
// valid transaction must have at least one output.
ErrNoTxOutputs = ErrorKind("ErrNoTxOutputs")
// ErrInvalidTxOutputs indicates a transaction does not have the exact
// number of outputs.
ErrInvalidTxOutputs = ErrorKind("ErrInvalidTxOutputs")
// ErrTxTooBig indicates a transaction exceeds the maximum allowed size
// when serialized.
ErrTxTooBig = ErrorKind("ErrTxTooBig")
// ErrBadTxOutValue indicates an output value for a transaction is
// invalid in some way such as being out of range.
ErrBadTxOutValue = ErrorKind("ErrBadTxOutValue")
// ErrDuplicateTxInputs indicates a transaction references the same
// input more than once.
ErrDuplicateTxInputs = ErrorKind("ErrDuplicateTxInputs")
// ErrTxVersionTooHigh indicates a transaction version is higher than the
// maximum version allowed by the active consensus rules.
ErrTxVersionTooHigh = ErrorKind("ErrTxVersionTooHigh")
// 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 = ErrorKind("ErrBadTxInput")
// ErrScriptVersionTooHigh indicates a transaction script version is higher
// than the maximum version allowed by the active consensus rules.
ErrScriptVersionTooHigh = ErrorKind("ErrScriptVersionTooHigh")
// ErrMissingTxOut indicates a transaction output referenced by an input
// either does not exist or has already been spent.
ErrMissingTxOut = ErrorKind("ErrMissingTxOut")
// ErrUnfinalizedTx indicates a transaction has not been finalized.
// A valid block may only contain finalized transactions.
ErrUnfinalizedTx = ErrorKind("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 = ErrorKind("ErrDuplicateTx")
// ErrOverwriteTx indicates a block contains a transaction that has
// the same hash as a previous transaction which has not been fully
// spent.
ErrOverwriteTx = ErrorKind("ErrOverwriteTx")
// ErrImmatureSpend indicates a transaction is attempting to spend a
// coinbase that has not yet reached the required maturity.
ErrImmatureSpend = ErrorKind("ErrImmatureSpend")
// ErrSpendTooHigh indicates a transaction is attempting to spend more
// value than the sum of all of its inputs.
ErrSpendTooHigh = ErrorKind("ErrSpendTooHigh")
// ErrBadFees indicates the total fees for a block are invalid due to
// exceeding the maximum possible value.
ErrBadFees = ErrorKind("ErrBadFees")
// ErrTooManySigOps indicates the total number of signature operations
// for a transaction or block exceed the maximum allowed limits.
ErrTooManySigOps = ErrorKind("ErrTooManySigOps")
// ErrFirstTxNotCoinbase indicates the first transaction in a block
// is not a coinbase transaction.
ErrFirstTxNotCoinbase = ErrorKind("ErrFirstTxNotCoinbase")
// ErrCoinbaseHeight indicates that the encoded height in the coinbase
// is incorrect.
ErrCoinbaseHeight = ErrorKind("ErrCoinbaseHeight")
// ErrMultipleCoinbases indicates a block contains more than one
// coinbase transaction.
ErrMultipleCoinbases = ErrorKind("ErrMultipleCoinbases")
// ErrStakeTxInRegularTree indicates a stake transaction was found in
// the regular transaction tree.
ErrStakeTxInRegularTree = ErrorKind("ErrStakeTxInRegularTree")
// ErrRegTxInStakeTree indicates that a regular transaction was found in
// the stake transaction tree.
ErrRegTxInStakeTree = ErrorKind("ErrRegTxInStakeTree")
// ErrBadCoinbaseScriptLen indicates the length of the signature script
// for a coinbase transaction is not within the valid range.
ErrBadCoinbaseScriptLen = ErrorKind("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 = ErrorKind("ErrBadCoinbaseValue")
// ErrBadCoinbaseOutpoint indicates that the outpoint used by a coinbase
// as input was non-null.
ErrBadCoinbaseOutpoint = ErrorKind("ErrBadCoinbaseOutpoint")
// ErrBadCoinbaseFraudProof indicates that the fraud proof for a coinbase
// input was non-null.
ErrBadCoinbaseFraudProof = ErrorKind("ErrBadCoinbaseFraudProof")
// ErrBadCoinbaseAmountIn indicates that the AmountIn (=subsidy) for a
// coinbase input was incorrect.
ErrBadCoinbaseAmountIn = ErrorKind("ErrBadCoinbaseAmountIn")
// ErrBadStakebaseAmountIn indicates that the AmountIn (=subsidy) for a
// stakebase input was incorrect.
ErrBadStakebaseAmountIn = ErrorKind("ErrBadStakebaseAmountIn")
// ErrBadStakebaseScriptLen indicates the length of the signature script
// for a stakebase transaction is not within the valid range.
ErrBadStakebaseScriptLen = ErrorKind("ErrBadStakebaseScriptLen")
// ErrBadStakebaseScrVal indicates the signature script for a stakebase
// transaction was not set to the network consensus value.
ErrBadStakebaseScrVal = ErrorKind("ErrBadStakebaseScrVal")
// 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 = ErrorKind("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 = ErrorKind("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 = ErrorKind("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 = ErrorKind("ErrStakeBelowMinimum")
// ErrNonstandardStakeTx indicates that a block contained a stake tx that
// was not one of the allowed types of a stake transactions.
ErrNonstandardStakeTx = ErrorKind("ErrNonstandardStakeTx")
// ErrNotEnoughVotes indicates that a block contained less than a majority
// of voters.
ErrNotEnoughVotes = ErrorKind("ErrNotEnoughVotes")
// ErrTooManyVotes indicates that a block contained more than the maximum
// allowable number of votes.
ErrTooManyVotes = ErrorKind("ErrTooManyVotes")
// ErrFreshStakeMismatch indicates that a block's header contained a different
// number of SStx as compared to what was found in the block.
ErrFreshStakeMismatch = ErrorKind("ErrFreshStakeMismatch")
// ErrTooManySStxs indicates that more than the allowed number of SStx was
// found in a block.
ErrTooManySStxs = ErrorKind("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 = ErrorKind("ErrInvalidEarlyStakeTx")
// ErrTicketUnavailable indicates that a vote in the block spent a ticket
// that could not be found.
ErrTicketUnavailable = ErrorKind("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 = ErrorKind("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 = ErrorKind("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 = ErrorKind("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 = ErrorKind("ErrInvalidSSRtx")
// ErrInvalidRevNum indicates that the number of revocations from the
// header was not the same as the number of SSRtx included in the block.
ErrRevocationsMismatch = ErrorKind("ErrRevocationsMismatch")
// ErrTooManyRevocations indicates more revocations were found in a block
// than were allowed.
ErrTooManyRevocations = ErrorKind("ErrTooManyRevocations")
// ErrTicketCommitment indicates that a ticket commitment contains an amount
// that does not coincide with the associated ticket input amount.
ErrTicketCommitment = ErrorKind("ErrTicketCommitment")
// ErrInvalidVoteInput indicates that an input to a vote transaction is
// either not a stake ticket submission or is not a supported version.
ErrInvalidVoteInput = ErrorKind("ErrInvalidVoteInput")
// ErrBadNumPayees indicates that either a vote or revocation transaction
// does not make the correct number of payments per the associated ticket
// commitments.
ErrBadNumPayees = ErrorKind("ErrBadNumPayees")
// ErrBadPayeeScriptVersion indicates that either a vote or revocation
// transaction output that corresponds to a ticket commitment does not use
// a supported script version.
ErrBadPayeeScriptVersion = ErrorKind("ErrBadPayeeScriptVersion")
// ErrBadPayeeScriptType indicates that either a vote or revocation
// transaction output that corresponds to a ticket commitment does not pay
// to the same script type required by the commitment.
ErrBadPayeeScriptType = ErrorKind("ErrBadPayeeScriptType")
// ErrBadPayeeScriptType indicates that either a vote or revocation
// transaction output that corresponds to a ticket commitment does not pay
// to the hash required by the commitment.
ErrMismatchedPayeeHash = ErrorKind("ErrMismatchedPayeeHash")
// ErrBadPayeeValue indicates that either a vote or revocation transaction
// output that corresponds to a ticket commitment does not pay the expected
// amount required by the commitment.
ErrBadPayeeValue = ErrorKind("ErrBadPayeeValue")
// ErrSSGenSubsidy indicates that there was an error in the amount of subsidy
// generated in the vote.
ErrSSGenSubsidy = ErrorKind("ErrSSGenSubsidy")
// ErrImmatureTicketSpend indicates that a vote or revocation is attempting
// to spend a ticket submission output that has not yet reached the required
// maturity.
ErrImmatureTicketSpend = ErrorKind("ErrImmatureTicketSpend")
// ErrTicketInputScript indicates that a ticket input is not one of the
// supported script forms or versions.
ErrTicketInputScript = ErrorKind("ErrTicketInputScript")
// ErrInvalidRevokeInput indicates that an input to a revocation transaction
// is either not a stake ticket submission or is not a supported version.
ErrInvalidRevokeInput = ErrorKind("ErrInvalidRevokeInput")
// ErrSSRtxPayees indicates that the SSRtx failed to pay out to the committed
// addresses or amounts from the originating SStx.
ErrSSRtxPayees = ErrorKind("ErrSSRtxPayees")
// ErrTxSStxOutSpend indicates that a non SSGen or SSRtx tx attempted to spend
// an OP_SSTX tagged output from an SStx.
ErrTxSStxOutSpend = ErrorKind("ErrTxSStxOutSpend")
// ErrRegTxCreateStakeOut indicates that a regular tx attempted to create
// a stake tagged output.
ErrRegTxCreateStakeOut = ErrorKind("ErrRegTxCreateStakeOut")
// ErrInvalidFinalState indicates that the final state of the PRNG included
// in the block differed from the calculated final state.
ErrInvalidFinalState = ErrorKind("ErrInvalidFinalState")
// ErrPoolSize indicates an error in the ticket pool size for this block.
ErrPoolSize = ErrorKind("ErrPoolSize")
// ErrForceReorgSameBlock indicates that a reorganization was attempted to
// be forced to the same block.
ErrForceReorgSameBlock = ErrorKind("ErrForceReorgSameBlock")
// ErrForceReorgWrongChain indicates that a reorganization was attempted
// to be forced, but the chain indicated was not mirrored by b.bestChain.
ErrForceReorgWrongChain = ErrorKind("ErrForceReorgWrongChain")
// ErrForceReorgMissingChild indicates that a reorganization was attempted
// to be forced, but the child node to reorganize to could not be found.
ErrForceReorgMissingChild = ErrorKind("ErrForceReorgMissingChild")
// ErrBadStakebaseValue indicates that a block's stake tx tree has spent
// more than it is allowed.
ErrBadStakebaseValue = ErrorKind("ErrBadStakebaseValue")
// ErrStakeFees indicates an error with the fees found in the stake
// transaction tree.
ErrStakeFees = ErrorKind("ErrStakeFees")
// ErrNoStakeTx indicates there were no stake transactions found in a
// block after stake validation height.
ErrNoStakeTx = ErrorKind("ErrNoStakeTx")
// ErrBadBlockHeight indicates that a block header's embedded block height
// was different from where it was actually embedded in the block chain.
ErrBadBlockHeight = ErrorKind("ErrBadBlockHeight")
// ErrBlockOneTx indicates that block height 1 failed to correct generate
// the block one initial payout transaction.
ErrBlockOneTx = ErrorKind("ErrBlockOneTx")
// ErrBlockOneTx indicates that block height 1 coinbase transaction in
// zero was incorrect in some way.
ErrBlockOneInputs = ErrorKind("ErrBlockOneInputs")
// ErrBlockOneOutputs indicates that block height 1 failed to incorporate
// the ledger addresses correctly into the transaction's outputs.
ErrBlockOneOutputs = ErrorKind("ErrBlockOneOutputs")
// ErrNoTax indicates that there was no tax present in the coinbase of a
// block after height 1.
ErrNoTax = ErrorKind("ErrNoTax")
// ErrExpiredTx indicates that the transaction is currently expired.
ErrExpiredTx = ErrorKind("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 = ErrorKind("ErrExpiryTxSpentEarly")
// ErrFraudAmountIn indicates the witness amount given was fraudulent.
ErrFraudAmountIn = ErrorKind("ErrFraudAmountIn")
// ErrFraudBlockHeight indicates the witness block height given was
// fraudulent.
ErrFraudBlockHeight = ErrorKind("ErrFraudBlockHeight")
// ErrFraudBlockIndex indicates the witness block index given was
// fraudulent.
ErrFraudBlockIndex = ErrorKind("ErrFraudBlockIndex")
// ErrZeroValueOutputSpend indicates that a transaction attempted to spend a
// zero value output.
ErrZeroValueOutputSpend = ErrorKind("ErrZeroValueOutputSpend")
// ErrInvalidEarlyVoteBits indicates that a block before stake validation
// height had an unallowed vote bits value.
ErrInvalidEarlyVoteBits = ErrorKind("ErrInvalidEarlyVoteBits")
// ErrInvalidEarlyFinalState indicates that a block before stake validation
// height had a non-zero final state.
ErrInvalidEarlyFinalState = ErrorKind("ErrInvalidEarlyFinalState")
// ErrKnownInvalidBlock indicates that this block has previously failed
// validation.
ErrKnownInvalidBlock = ErrorKind("ErrKnownInvalidBlock")
// ErrInvalidAncestorBlock indicates that an ancestor of this block has
// failed validation.
ErrInvalidAncestorBlock = ErrorKind("ErrInvalidAncestorBlock")
// ErrInvalidTemplateParent indicates that a block template builds on a
// block that is either not the current best chain tip or its parent.
ErrInvalidTemplateParent = ErrorKind("ErrInvalidTemplateParent")
// ErrUnknownPiKey indicates that the provided public Pi Key is not
// a well known key.
ErrUnknownPiKey = ErrorKind("ErrUnknownPiKey")
// ErrInvalidPiSignature indicates that a treasury spend transaction
// was not properly signed.
ErrInvalidPiSignature = ErrorKind("ErrInvalidPiSignature")
// ErrInvalidTVoteWindow indicates that a treasury spend transaction
// appeared in a block that is prior to a valid treasury vote window.
ErrInvalidTVoteWindow = ErrorKind("ErrInvalidTVoteWindow")
// ErrNotTVI indicates that a treasury spend transaction appeared in a
// block that is not at a TVI interval.
ErrNotTVI = ErrorKind("ErrNotTVI")
// ErrInvalidTSpendWindow indicates that this treasury spend
// transaction is outside of the allowed window.
ErrInvalidTSpendWindow = ErrorKind("ErrInvalidTSpendWindow")
// ErrNotEnoughTSpendVotes indicates that a treasury spend transaction
// does not have enough votes to be included in block.
ErrNotEnoughTSpendVotes = ErrorKind("ErrNotEnoughTSpendVotes")
// ErrInvalidTSpendValueIn indicates that a treasury spend transaction
// ValueIn does not match the encoded copy in the first TxOut.
ErrInvalidTSpendValueIn = ErrorKind("ErrInvalidTSpendValueIn")
// ErrTSpendExists indicates that a duplicate treasury spend
// transaction has been mined on a TVI in the current best chain.
ErrTSpendExists = ErrorKind("ErrTSpendExists")
// ErrInvalidExpenditure indicates that a treasury spend transaction
// expenditure is out of range.
ErrInvalidExpenditure = ErrorKind("ErrInvalidExpenditure")
// ErrFirstTxNotTreasurybase indicates the first transaction in a block
// is not a treasurybase transaction.
ErrFirstTxNotTreasurybase = ErrorKind("ErrFirstTxNotTreasurybase")
// ErrBadTreasurybaseOutpoint indicates that the outpoint used by a
// treasurybase as input was non-null.
ErrBadTreasurybaseOutpoint = ErrorKind("ErrBadTreasurybaseOutpoint")
// ErrBadTreasurybaseFraudProof indicates that the fraud proof for a
// treasurybase input was non-null.
ErrBadTreasurybaseFraudProof = ErrorKind("ErrBadTreasurybaseFraudProof")
// ErrBadTreasurybaseScriptLen indicates the length of the signature script
// for a treasurybase transaction is not within the valid range.
ErrBadTreasurybaseScriptLen = ErrorKind("ErrBadTreasurybaseScriptLen")
// ErrTreasurybaseTxNotOpReturn indicates the second output of a
// treasury base transaction is not an OP_RETURN.
ErrTreasurybaseTxNotOpReturn = ErrorKind("ErrTreasurybaseTxNotOpReturn")
// ErrTreasurybaseHeight indicates that the encoded height in the
// treasurybase is incorrect.
ErrTreasurybaseHeight = ErrorKind("ErrTreasurybaseHeight")
// ErrInvalidTreasurybaseTxOutputs indicates that the transaction does
// not have the correct number of outputs.
ErrInvalidTreasurybaseTxOutputs = ErrorKind("ErrInvalidTreasurybaseTxOutputs")
// ErrInvalidTreasurybaseVersion indicates that the transaction output
// has the wrong version.
ErrInvalidTreasurybaseVersion = ErrorKind("ErrInvalidTreasurybaseVersion")
// ErrInvalidTreasurybaseScript indicates that the transaction output
// script is invalid.
ErrInvalidTreasurybaseScript = ErrorKind("ErrInvalidTreasurybaseScript")
// ErrTreasurybaseOutValue ensures that the OP_TADD value of a
// treasurybase is not the expected amount.
ErrTreasurybaseOutValue = ErrorKind("ErrTreasurybaseOutValue")
// ErrMultipleTreasurybases indicates a block contains more than one
// treasurybase transaction.
ErrMultipleTreasurybases = ErrorKind("ErrMultipleTreasurybases")
// ErrBadTreasurybaseAmountIn indicates that a block contains an
// invalid treasury contribution.
ErrBadTreasurybaseAmountIn = ErrorKind("ErrBadTreasurybaseAmountIn")
// ErrBadTSpendOutpoint indicates that the outpoint used by a
// treasury spend as input was non-null.
ErrBadTSpendOutpoint = ErrorKind("ErrBadTSpendOutpoint")
// ErrBadTSpendFraudProof indicates that the fraud proof for a treasury
// spend transaction input was non-null.
ErrBadTSpendFraudProof = ErrorKind("ErrBadTSpendFraudProof")
// ErrBadTSpendScriptLen indicates the length of the signature script
// for a treasury spend transaction is not within the valid range.
ErrBadTSpendScriptLen = ErrorKind("ErrBadTSpendScriptLen")
// ErrInvalidTAddChange indicates the change output of a TAdd is zero.
ErrInvalidTAddChange = ErrorKind("ErrInvalidTAddChange")
// ErrTooManyTAdds indicates the number of treasury adds in a given
// block is larger than the maximum allowed.
ErrTooManyTAdds = ErrorKind("ErrTooManyTAdds")
// ErrTicketExhaustion indicates extending a given block with another one
// would result in an unrecoverable chain due to ticket exhaustion.
ErrTicketExhaustion = ErrorKind("ErrTicketExhaustion")
// ErrDBTooOldToUpgrade indicates the database version is prior to the
// minimum supported version for which upgrades are supported.
ErrDBTooOldToUpgrade = ErrorKind("ErrDBTooOldToUpgrade")
// ErrUnknownDeploymentID indicates a deployment id does not exist.
ErrUnknownDeploymentID = ErrorKind("ErrUnknownDeploymentID")
// ErrUnknownDeploymentVersion indicates a version for a given deployment id
// was specified that does not exist.
ErrUnknownDeploymentVersion = ErrorKind("ErrUnknownDeploymentVersion")
// ErrDuplicateDeployment indicates a duplicate deployment id exists in the
// network parameter deployment definitions.
ErrDuplicateDeployment = ErrorKind("ErrDuplicateDeployment")
// ErrUnknownBlock indicates a requested block does not exist.
ErrUnknownBlock = ErrorKind("ErrUnknownBlock")
// ErrNoFilter indicates a filter for a given block hash does not exist.
ErrNoFilter = ErrorKind("ErrNoFilter")
// ErrNoTreasuryBalance indicates the treasury balance for a given block
// hash does not exist.
ErrNoTreasuryBalance = ErrorKind("ErrNoTreasuryBalance")
// ErrInvalidateGenesisBlock indicates an attempt to invalidate the genesis
// block which is not allowed.
ErrInvalidateGenesisBlock = ErrorKind("ErrInvalidateGenesisBlock")
// ErrSerializeHeader indicates an attempt to serialize a block header failed.
ErrSerializeHeader = ErrorKind("ErrSerializeHeader")
// ------------------------------------------
// Errors related to the UTXO backend.
// ------------------------------------------
// ErrUtxoBackend indicates that a general error was encountered when
// accessing the UTXO backend.
ErrUtxoBackend = ErrorKind("ErrUtxoBackend")
// ErrUtxoBackendCorruption indicates that underlying data being accessed in
// the UTXO backend is corrupted.
ErrUtxoBackendCorruption = ErrorKind("ErrUtxoBackendCorruption")
// ErrUtxoBackendNotOpen indicates that the UTXO backend was accessed before
// it was opened or after it was closed.
ErrUtxoBackendNotOpen = ErrorKind("ErrUtxoBackendNotOpen")
// ErrUtxoBackendTxClosed indicates an attempt was made to commit or rollback
// a UTXO backend transaction that has already had one of those operations
// performed.
ErrUtxoBackendTxClosed = ErrorKind("ErrUtxoBackendTxClosed")
// -----------------------------------------------------------------
// Errors related to the automatic ticket revocations agenda.
// -----------------------------------------------------------------
// ErrInvalidRevocationTxVersion indicates that the revocation is the wrong
// transaction version.
ErrInvalidRevocationTxVersion = ErrorKind("ErrInvalidRevocationTxVersion")
// ErrNoExpiredTicketRevocation indicates that the block does not contain a
// revocation for a ticket that is becoming expired as of that block.
ErrNoExpiredTicketRevocation = ErrorKind("ErrNoExpiredTicketRevocation")
// ErrNoMissedTicketRevocation indicates that the block does not contain a
// revocation for a ticket that is becoming missed as of that block.
ErrNoMissedTicketRevocation = ErrorKind("ErrNoMissedTicketRevocation")
)
// Error satisfies the error interface and prints human-readable errors.
func (e ErrorKind) Error() string {
return string(e)
}
// ContextError wraps an error with additional context. It has full support for
// errors.Is and errors.As, so the caller can ascertain the specific wrapped
// error.
//
// RawErr contains the original error in the case where an error has been
// converted.
type ContextError struct {
Err error
Description string
RawErr error
}
// Error satisfies the error interface and prints human-readable errors.
func (e ContextError) Error() string {
return e.Description
}
// Unwrap returns the underlying wrapped error.
func (e ContextError) Unwrap() error {
return e.Err
}
// contextError creates a ContextError given a set of arguments.
func contextError(kind ErrorKind, desc string) ContextError {
return ContextError{Err: kind, Description: desc}
}
// unknownBlockError create a ContextError with the kind of error set to
// ErrUnknownBlock and a description that includes the provided hash.
func unknownBlockError(hash *chainhash.Hash) ContextError {
str := fmt.Sprintf("block %s is not known", hash)
return contextError(ErrUnknownBlock, str)
}
// 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. It has full support for errors.Is and errors.As, so the caller can
// ascertain the specific reason for the rule violation.
type RuleError struct {
Err error
Description string
}
// Error satisfies the error interface and prints human-readable errors.
func (e RuleError) Error() string {
return e.Description
}
// Unwrap returns the underlying wrapped error.
func (e RuleError) Unwrap() error {
return e.Err
}
// ruleError creates a RuleError given a set of arguments.
func ruleError(kind ErrorKind, desc string) RuleError {
return RuleError{Err: kind, Description: desc}
}
// MultiError houses several errors as a single error that provides full support
// for errors.Is and errors.As so the caller can easily determine if any of the
// errors match any specific error or error type. Note that this differs from
// typical wrapped error chains which only represent a single error.
type MultiError []error
// Error satisfies the error interface and prints human-readable errors.
func (e MultiError) Error() string {
if len(e) == 1 {
return e[0].Error()
}
var builder strings.Builder
builder.WriteString("multiple errors (")
builder.WriteString(strconv.Itoa(len(e)))
builder.WriteString("):\n")
const maxErrs = 5
i := 0
for ; i < len(e) && i < maxErrs; i++ {
builder.WriteString(" - ")
builder.WriteString(e[i].Error())
builder.WriteRune('\n')
}
if len(e) > maxErrs {
builder.WriteString(" - ... ")
builder.WriteString(strconv.Itoa(len(e) - maxErrs))
builder.WriteString(" more error(s)")
builder.WriteRune('\n')
}
return builder.String()
}
// Is implements the interface to work with the standard library's errors.Is.
//
// It iterates each of the errors in the multi error and calls errors.Is on it
// until the first one that matches target is found, in which case it returns
// true. Otherwise, it returns false.
//
// This means it keeps all of the same semantics typically provided by Is in
// terms of unwrapping error chains.
func (e MultiError) Is(target error) bool {
for _, err := range e {
if errors.Is(err, target) {
return true
}
}
return false
}
// As implements the interface to work with the standard library's errors.As.
//
// It iterates each of the errors in the multi error and calls errors.As on it
// until the first one that matches target is found, in which case it returns
// true. Otherwise, it returns false.
//
// This means it keeps all of the same semantics typically provided by As in
// terms of unwrapping error chains and setting the target to the matched error.
func (e MultiError) As(target interface{}) bool {
for _, err := range e {
if errors.As(err, target) {
return true
}
}
return false
}