150 lines
5.1 KiB
Go
150 lines
5.1 KiB
Go
// Copyright (c) 2014-2016 The btcsuite developers
|
|
// Copyright (c) 2015-2023 The Decred developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package mempool
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/decred/dcrd/internal/blockchain"
|
|
)
|
|
|
|
// 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
|
|
|
|
const (
|
|
// ErrInvalid indicates a mempool transaction is invalid per consensus.
|
|
ErrInvalid = ErrorKind("ErrInvalid")
|
|
|
|
// ErrOrphanPolicyViolation indicates that an orphan block violates the
|
|
// prevailing orphan policy.
|
|
ErrOrphanPolicyViolation = ErrorKind("ErrOrphanPolicyViolation")
|
|
|
|
// ErrMempoolDoubleSpend indicates a transaction that attempts to spend
|
|
// coins already spent by other transactions in the pool.
|
|
ErrMempoolDoubleSpend = ErrorKind("ErrMempoolDoubleSpend")
|
|
|
|
// ErrAlreadyVoted indicates a ticket already voted.
|
|
ErrAlreadyVoted = ErrorKind("ErrorAlreadyVoted")
|
|
|
|
// ErrDuplicate indicates a transaction already exists in the mempool.
|
|
ErrDuplicate = ErrorKind("ErrDuplicate")
|
|
|
|
// ErrCoinbase indicates a transaction is a standalone coinbase transaction.
|
|
ErrCoinbase = ErrorKind("ErrCoinbase")
|
|
|
|
// ErrTreasurybase indicates a transaction is a standalone treasurybase
|
|
// transaction.
|
|
ErrTreasurybase = ErrorKind("ErrTreasurybase")
|
|
|
|
// ErrExpired indicates a transaction will be expired as of the next block.
|
|
ErrExpired = ErrorKind("ErrExpired")
|
|
|
|
// ErrNonStandard indicates a non-standard transaction.
|
|
ErrNonStandard = ErrorKind("ErrNonStandard")
|
|
|
|
// ErrDustOutput indicates a transaction has one or more dust outputs.
|
|
ErrDustOutput = ErrorKind("ErrDustOutput")
|
|
|
|
// ErrInsufficientFee indicates a transaction cannot does not pay the minimum
|
|
// fee required by the active policy.
|
|
ErrInsufficientFee = ErrorKind("ErrInsufficientFee")
|
|
|
|
// ErrTooManyVotes indicates the number of vote double spends exceeds the
|
|
// maximum allowed.
|
|
ErrTooManyVotes = ErrorKind("ErrTooManyVotes")
|
|
|
|
// ErrDuplicateRevocation indicates a revocation already exists in the
|
|
// mempool.
|
|
ErrDuplicateRevocation = ErrorKind("ErrDuplicateRevocation")
|
|
|
|
// ErrOldVote indicates a ticket votes on a block height lower than
|
|
// the minimum allowed by the mempool.
|
|
ErrOldVote = ErrorKind("ErrOldVote")
|
|
|
|
// ErrAlreadyExists indicates a transaction already exists on the
|
|
// main chain and is not fully spent.
|
|
ErrAlreadyExists = ErrorKind("ErrAlreadyExists")
|
|
|
|
// ErrSeqLockUnmet indicates a transaction sequence locks are not active.
|
|
ErrSeqLockUnmet = ErrorKind("ErrSeqLockUnmet")
|
|
|
|
// ErrFeeTooHigh indicates a transaction pays fees above the maximum
|
|
// allowed by the active policy.
|
|
ErrFeeTooHigh = ErrorKind("ErrFeeTooHigh")
|
|
|
|
// ErrOrphan indicates a transaction is an orphan.
|
|
ErrOrphan = ErrorKind("ErrOrphan")
|
|
|
|
// ErrTooManyTSpends indicates the number of treasury spend hashes exceeds
|
|
// the maximum allowed.
|
|
ErrTooManyTSpends = ErrorKind("ErrTooManyTSpends")
|
|
|
|
// ErrTSpendMinedOnAncestor indicates a referenced treasury spend was
|
|
// already mined on an ancestor block.
|
|
ErrTSpendMinedOnAncestor = ErrorKind("ErrTSpendMinedOnAncestor")
|
|
|
|
// ErrTSpendInvalidExpiry indicates a treasury spend expiry is invalid.
|
|
ErrTSpendInvalidExpiry = ErrorKind("ErrTSpendInvalidExpiry")
|
|
)
|
|
|
|
// Error satisfies the error interface and prints human-readable errors.
|
|
func (e ErrorKind) Error() string {
|
|
return string(e)
|
|
}
|
|
|
|
// RuleError identifies a rule violation. It is used to indicate that
|
|
// processing of a 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 error by checking the
|
|
// underlying error, which will be either an ErrorKind or blockchain.RuleError.
|
|
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
|
|
}
|
|
|
|
// chainRuleError returns a RuleError that encapsulates the given
|
|
// blockchain.RuleError.
|
|
func chainRuleError(chainErr blockchain.RuleError) RuleError {
|
|
return RuleError{Err: chainErr, Description: chainErr.Description}
|
|
}
|
|
|
|
// txRuleError creates a RuleError given a set of arguments.
|
|
func txRuleError(kind ErrorKind, desc string) RuleError {
|
|
return RuleError{Err: kind, Description: desc}
|
|
}
|
|
|
|
// wrapTxRuleError returns a new RuleError with an underlying ErrorKind,
|
|
// replacing the description with the provided one while retaining the error
|
|
// kind from the original error if it can be determined.
|
|
func wrapTxRuleError(kind ErrorKind, desc string, err error) error {
|
|
// Override the passed error kind with the one from the error if it is an
|
|
// ErrorKind.
|
|
var kerr ErrorKind
|
|
if errors.As(err, &kerr) {
|
|
kind = kerr
|
|
}
|
|
|
|
// Fill a default error description if empty.
|
|
if desc == "" {
|
|
desc = fmt.Sprintf("rejected: %v", err)
|
|
}
|
|
|
|
return txRuleError(kind, desc)
|
|
}
|