780 lines
32 KiB
Go
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
|
|
}
|