This adds additional stake error kinds that will be used by the automatic ticket revocations agenda implementation.
336 lines
14 KiB
Go
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}
|
|
}
|