dcrd/blockchain/stake/error.go
Ryan Staudt 7eae1a1e63 stake: Add auto revocation error kinds.
This adds additional stake error kinds that will be used by the
automatic ticket revocations agenda implementation.
2021-09-06 08:48:19 -05:00

336 lines
14 KiB
Go

// Copyright (c) 2014 Conformal Systems LLC.
// 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 stake
// 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 RuleError.
const (
// ErrSStxTooManyInputs indicates that a given SStx contains too many
// inputs.
ErrSStxTooManyInputs = ErrorKind("ErrSStxTooManyInputs")
// ErrSStxTooManyOutputs indicates that a given SStx contains too many
// outputs.
ErrSStxTooManyOutputs = ErrorKind("ErrSStxTooManyOutputs")
// ErrSStxNoOutputs indicates that a given SStx has no outputs.
ErrSStxNoOutputs = ErrorKind("ErrSStxNoOutputs")
// ErrSStxInvalidInput indicates that an invalid output has been used as
// an input for a SStx; only non-SStx tagged outputs may be used to
// purchase stake tickets.
// TODO: Add this into validate
// Ensure that all inputs are not tagged SStx outputs of some sort,
// along with checks to make sure they exist and are available.
ErrSStxInvalidInputs = ErrorKind("ErrSStxInvalidInputs")
// ErrSStxInvalidOutput indicates that the output for an SStx tx is
// invalid; in particular, either the output was not tagged SStx or the
// OP_RETURNs were missing or contained invalid addresses.
ErrSStxInvalidOutputs = ErrorKind("ErrSStxInvalidOutputs")
// ErrSStxInOutProportions indicates the number of inputs in an SStx
// was not equal to the number of output minus one.
ErrSStxInOutProportions = ErrorKind("ErrSStxInOutProportions")
// ErrSStxBadCommitAmount indicates that a ticket tried to commit 0 or
// a negative value as the commitment amount.
ErrSStxBadCommitAmount = ErrorKind("ErrSStxBadCommitAmount")
// ErrSStxBadChangeAmts indicates that the change amount for some SStx
// was invalid, for instance spending more than its inputs.
ErrSStxBadChangeAmts = ErrorKind("ErrSStxBadChangeAmts")
// ErrSStxVerifyCalcAmts indicates that passed calculated amounts failed
// to conform to the amounts found in the ticket.
ErrSStxVerifyCalcAmts = ErrorKind("ErrSStxVerifyCalcAmts")
// ErrSSGenWrongNumInputs indicates that a given SSGen tx contains an
// invalid number of inputs.
ErrSSGenWrongNumInputs = ErrorKind("ErrSSGenWrongNumInputs")
// ErrSSGenTooManyOutputs indicates that a given SSGen tx contains too
// many outputs.
ErrSSGenTooManyOutputs = ErrorKind("ErrSSGenTooManyOutputs")
// ErrSSGenNoOutputs indicates that a given SSGen has no outputs.
ErrSSGenNoOutputs = ErrorKind("ErrSSGenNoOutputs")
// ErrSSGenWrongIndex indicates that a given SSGen sstx input was not
// using the correct index.
ErrSSGenWrongIndex = ErrorKind("ErrSSGenWrongIndex")
// ErrSSGenWrongTxTree indicates that a given SSGen tx input was not found in
// the stake tx tree.
ErrSSGenWrongTxTree = ErrorKind("ErrSSGenWrongTxTree")
// ErrSSGenNoStakebase indicates that the SSGen tx did not contain a
// valid StakeBase in the zeroeth position of inputs.
ErrSSGenNoStakebase = ErrorKind("ErrSSGenNoStakebase")
// ErrSSGenNoReference indicates that there is no reference OP_RETURN
// included as the first output.
ErrSSGenNoReference = ErrorKind("ErrSSGenNoReference")
// ErrSSGenNoReference indicates that the OP_RETURN included as the
// first output was corrupted in some way.
ErrSSGenBadReference = ErrorKind("ErrSSGenBadReference")
// ErrSSGenNoVotePush indicates that there is no vote bits OP_RETURN
// included as the second output.
ErrSSGenNoVotePush = ErrorKind("ErrSSGenNoVotePush")
// ErrSSGenBadVotePush indicates that the OP_RETURN included as the
// second output was corrupted in some way.
ErrSSGenBadVotePush = ErrorKind("ErrSSGenBadVotePush")
// ErrSSGenInvalidDiscriminatorLength indicates that the discriminator
// length is too short.
ErrSSGenInvalidDiscriminatorLength = ErrorKind("ErrSSGenInvalidDiscriminatorLength")
// ErrSSGenInvalidNullScript indicates that the passed script is not a
// valid nullscript.
ErrSSGenInvalidNullScript = ErrorKind("ErrSSGenInvalidNullScript")
// ErrSSGenInvalidTVLength indicates that this is an invalid Treasury
// Vote length.
ErrSSGenInvalidTVLength = ErrorKind("ErrSSGenInvalidTVLength")
// ErrSSGenInvalidTreasuryVote indicates that this is an invalid
// treasury vote.
ErrSSGenInvalidTreasuryVote = ErrorKind("ErrSSGenInvalidTreasuryVote")
// ErrSSGenDuplicateTreasuryVote indicates that there is a duplicate
// treasury vote.
ErrSSGenDuplicateTreasuryVote = ErrorKind("ErrSSGenDuplicateTreasuryVote")
// ErrSSGenInvalidTxVersion indicates that this transaction has the
// wrong version.
ErrSSGenInvalidTxVersion = ErrorKind("ErrSSGenInvalidTxVersion")
// ErrSSGenUnknownDiscriminator indicates that the supplied
// discriminator is unsupported.
ErrSSGenUnknownDiscriminator = ErrorKind("ErrSSGenUnknownDiscriminator")
// ErrSSGenBadGenOuts indicates that something was wrong with the stake
// generation outputs that were present after the first two OP_RETURN
// pushes in an SSGen tx.
ErrSSGenBadGenOuts = ErrorKind("ErrSSGenBadGenOuts")
// ErrSSRtxWrongNumInputs indicates that a given SSRtx contains an
// invalid number of inputs.
ErrSSRtxWrongNumInputs = ErrorKind("ErrSSRtxWrongNumInputs")
// ErrSSRtxTooManyOutputs indicates that a given SSRtx contains too many
// outputs.
ErrSSRtxTooManyOutputs = ErrorKind("ErrSSRtxTooManyOutputs")
// ErrSSRtxNoOutputs indicates that a given SSRtx has no outputs.
ErrSSRtxNoOutputs = ErrorKind("ErrSSRtxNoOutputs")
// ErrSSRtxWrongTxTree indicates that a given SSRtx input was not found in
// the stake tx tree.
ErrSSRtxWrongTxTree = ErrorKind("ErrSSRtxWrongTxTree")
// ErrSSRtxBadOuts indicates that there was a non-SSRtx tagged output
// present in an SSRtx.
ErrSSRtxBadOuts = ErrorKind("ErrSSRtxBadOuts")
// ErrSSRtxInvalidFee indicates that a given SSRtx contains an invalid fee.
ErrSSRtxInvalidFee = ErrorKind("ErrSSRtxInvalidFee")
// ErrSSRtxInputHasSigScript indicates that a given SSRtx input has a
// non-empty signature script.
ErrSSRtxInputHasSigScript = ErrorKind("ErrSSRtxInputHasSigScript")
// ErrSSRtxInvalidTxVersion indicates that a given SSRtx has an invalid
// transaction version.
ErrSSRtxInvalidTxVersion = ErrorKind("ErrSSRtxInvalidTxVersion")
// ErrVerSStxAmts indicates there was an error verifying the calculated
// SStx out amounts and the actual SStx out amounts.
ErrVerSStxAmts = ErrorKind("ErrVerSStxAmts")
// ErrVerifyInput indicates that there was an error in verification
// function input.
ErrVerifyInput = ErrorKind("ErrVerifyInput")
// ErrVerifyOutType indicates that there was a non-equivalence in the
// output type.
ErrVerifyOutType = ErrorKind("ErrVerifyOutType")
// ErrVerifyTooMuchFees indicates that a transaction's output gave
// too much in fees after taking into accounts the limits imposed
// by the SStx output's version field.
ErrVerifyTooMuchFees = ErrorKind("ErrVerifyTooMuchFees")
// ErrVerifySpendTooMuch indicates that a transaction's output spent more
// than it was allowed to spend based on the calculated subsidy or return
// for a vote or revocation.
ErrVerifySpendTooMuch = ErrorKind("ErrVerifySpendTooMuch")
// ErrVerifyOutputAmt indicates that for a vote/revocation spend output,
// the rule was given that it must exactly match the calculated maximum,
// however the amount in the output did not (e.g. it gave fees).
ErrVerifyOutputAmt = ErrorKind("ErrVerifyOutputAmt")
// ErrVerifyOutPkhs indicates that the recipient of the P2PKH or P2SH
// script was different from that indicated in the SStx input.
ErrVerifyOutPkhs = ErrorKind("ErrVerifyOutPkhs")
// ErrDatabaseCorrupt indicates a database inconsistency.
ErrDatabaseCorrupt = ErrorKind("ErrDatabaseCorrupt")
// ErrMissingDatabaseTx indicates that a node disconnection failed to
// pass a database transaction when attempted to remove a very old
// node.
ErrMissingDatabaseTx = ErrorKind("ErrMissingDatabaseTx")
// ErrMemoryCorruption indicates that memory has somehow become corrupt,
// for example invalid block header serialization from an in memory
// struct.
ErrMemoryCorruption = ErrorKind("ErrMemoryCorruption")
// ErrFindTicketIdxs indicates a failure to find the selected ticket
// indexes from the block header.
ErrFindTicketIdxs = ErrorKind("ErrFindTicketIdxs")
// ErrMissingTicket indicates that a ticket was missing in one of the
// ticket treaps when it was attempted to be fetched.
ErrMissingTicket = ErrorKind("ErrMissingTicket")
// ErrDuplicateTicket indicates that a duplicate ticket was attempted
// to be inserted into a ticket treap or the database.
ErrDuplicateTicket = ErrorKind("ErrDuplicateTicket")
// ErrUnknownTicketSpent indicates that an unknown ticket was spent by
// the block.
ErrUnknownTicketSpent = ErrorKind("ErrUnknownTicketSpent")
// ErrTAddInvalidTxVersion indicates that this transaction has the
// wrong version.
ErrTAddInvalidTxVersion = ErrorKind("ErrTAddInvalidTxVersion")
// ErrTAddInvalidCount indicates that this transaction contains an
// invalid TADD script count.
ErrTAddInvalidCount = ErrorKind("ErrTAddInvalidCount")
// ErrTAddInvalidVersion indicates that this transaction has an invalid
// version in an output script.
ErrTAddInvalidVersion = ErrorKind("ErrTAddInvalidVersion")
// ErrTAddInvalidScriptLength indicates that this transaction has a zero
// length output script.
ErrTAddInvalidScriptLength = ErrorKind("ErrTAddInvalidScriptLength")
// ErrTAddInvalidLength indicates that output 0 is not exactly 1 byte.
ErrTAddInvalidLength = ErrorKind("ErrTAddInvalidLength")
// ErrTAddInvalidOpcode indicates that this transaction does not have a
// TADD opcode.
ErrTAddInvalidOpcode = ErrorKind("ErrTAddInvalidOpcode")
// ErrTAddInvalidChange indicates that this transaction contains an
// invalid change script.
ErrTAddInvalidChange = ErrorKind("ErrTAddInvalidChange")
// ErrTSpendInvalidTxVersion indicates that this transaction has
// the wrong version.
ErrTSpendInvalidTxVersion = ErrorKind("ErrTSpendInvalidTxVersion")
// ErrTSpendInvalidLength indicates that this transaction has an
// invalid number of inputs and/or outputs.
ErrTSpendInvalidLength = ErrorKind("ErrTSpendInvalidLength")
// ErrTSpendInvalidVersion indicates that this transaction has an
// invalid version in an output script.
ErrTSpendInvalidVersion = ErrorKind("ErrTSpendInvalidVersion")
// ErrTSpendInvalidScriptLength indicates that the TSPEND transaction
// has outputs that have a zero length script.
ErrTSpendInvalidScriptLength = ErrorKind("ErrTSpendInvalidScriptLength")
// ErrTSpendInvalidPubkey indicates that this transaction contains an
// invalid public key.
ErrTSpendInvalidPubkey = ErrorKind("ErrTSpendInvalidPubkey")
// ErrTSpendInvalidScript indicates that this transaction does not
// match the required TSPEND transaction signature.
ErrTSpendInvalidScript = ErrorKind("ErrTSpendInvalidScript")
// ErrTSpendInvalidTGen indicates that the TSPEND transaction has
// outputs that are not tagged with OP_TGEN.
ErrTSpendInvalidTGen = ErrorKind("ErrTSpendInvalidTGen")
// ErrTSpendInvalidTransaction indicates that a TSPEND transaction
// output 0 does not have an a valid null data script.
ErrTSpendInvalidTransaction = ErrorKind("ErrTSpendInvalidTransaction")
// ErrTSpendInvalidSpendScript indicates that this transaction contains
// an invalid P2SH or P2PKH script.
ErrTSpendInvalidSpendScript = ErrorKind("ErrTSpendInvalidSpendScript")
// ErrTreasuryBaseInvalidTxVersion indicates that this transaction has
// the wrong version.
ErrTreasuryBaseInvalidTxVersion = ErrorKind("ErrTreasuryBaseInvalidTxVersion")
// ErrTreasuryBaseInvalidCount indicates that this transaction contains
// an invalid treasury base script count.
ErrTreasuryBaseInvalidCount = ErrorKind("ErrTreasuryBaseInvalidCount")
// ErrTreasuryBaseInvalidLength indicates that this transaction contains
// an invalid treasury base input script length.
ErrTreasuryBaseInvalidLength = ErrorKind("ErrTreasuryBaseInvalidLength")
// ErrTreasuryBaseInvalidVersion indicates that this transaction has an
// invalid version in an output script.
ErrTreasuryBaseInvalidVersion = ErrorKind("ErrTreasuryBaseInvalidVersion")
// ErrTreasuryBaseInvalidOpcode0 indicates that this transaction does
// not have a TADD opcode in TxOut[0].
ErrTreasuryBaseInvalidOpcode0 = ErrorKind("ErrTreasuryBaseInvalidOpcode0")
// ErrTreasuryBaseInvalidOpcode1 indicates that this transaction does
// not have an OP_RETURN opcode in TxOut[1].
ErrTreasuryBaseInvalidOpcode1 = ErrorKind("ErrTreasuryBaseInvalidOpcode1")
// ErrTreasuryBaseInvalid indicates that this transaction contains
// invalid treasurybase TxIn constants.
ErrTreasuryBaseInvalid = ErrorKind("ErrTreasuryBaseInvalid")
)
// Error satisfies the error interface and prints human-readable errors.
func (e ErrorKind) Error() string {
return string(e)
}
// RuleError identifies a rule violation related to stake transactions. It has
// full support for errors.Is and errors.As, so the caller can ascertain the
// specific reason for the error by checking the underlying error.
type RuleError struct {
Description string
Err error
}
// Error satisfies the error interface and prints human-readable errors.
func (e RuleError) Error() string {
return e.Description
}
// Unwrap returns the underlying wrapped rule error.
func (e RuleError) Unwrap() error {
return e.Err
}
// stakeRuleError creates a RuleError given a set of arguments.
func stakeRuleError(kind ErrorKind, desc string) RuleError {
return RuleError{Err: kind, Description: desc}
}