1 package blockchain
2 3 import (
4 "fmt"
5 )
6 7 // DeploymentError identifies an error that indicates a deployment ID was specified that does not exist.
8 type DeploymentError uint32
9 10 // Error returns the assertion error as a human-readable string and satisfies the error interface.
11 func (e DeploymentError) Error() string {
12 return fmt.Sprintf("deployment ID %d does not exist", uint32(e))
13 }
14 15 // AssertError identifies an error that indicates an internal code consistency issue and should be treated as a critical
16 // and unrecoverable error.
17 type AssertError string
18 19 // Error returns the assertion error as a human-readable string and satisfies the error interface.
20 func (e AssertError) Error() string {
21 return "assertion failed: " + string(e)
22 }
23 24 // ErrorCode identifies a kind of error.
25 type ErrorCode int
26 27 // These constants are used to identify a specific RuleError.
28 const (
29 // ErrDuplicateBlock indicates a block with the same hash already exists.
30 ErrDuplicateBlock ErrorCode = iota
31 // ErrBlockTooBig indicates the serialized block size exceeds the maximum allowed size.
32 ErrBlockTooBig
33 // ErrBlockWeightTooHigh indicates that the block's computed weight metric exceeds the maximum allowed value.
34 ErrBlockWeightTooHigh
35 // ErrBlockVersionTooOld indicates the block version is too old and is no longer accepted since the majority of the
36 // network has upgraded to a newer version.
37 ErrBlockVersionTooOld
38 // ErrInvalidTime indicates the time in the passed block has a precision that is more than one second. The chain
39 // consensus rules require timestamps to have a maximum precision of one second.
40 ErrInvalidTime
41 // ErrTimeTooOld indicates the time is either before the median time of the last several blocks per the chain
42 // consensus rules or prior to the most recent checkpoint.
43 ErrTimeTooOld
44 // ErrTimeTooNew indicates the time is too far in the future as compared the current time.
45 ErrTimeTooNew
46 // ErrDifficultyTooLow indicates the difficulty for the block is lower than the difficulty required by the most
47 // recent checkpoint.
48 ErrDifficultyTooLow
49 // ErrUnexpectedDifficulty indicates specified bits do not align with the expected value either because it doesn't
50 // match the calculated valued based on difficulty regarted rules or it is out of the valid range.
51 ErrUnexpectedDifficulty
52 // ErrHighHash indicates the block does not hash to a value which is lower than the required target difficultly.
53 ErrHighHash
54 // ErrBadMerkleRoot indicates the calculated merkle root does not match the expected value.
55 ErrBadMerkleRoot
56 // ErrBadCheckpoint indicates a block that is expected to be at a checkpoint height does not match the expected one.
57 ErrBadCheckpoint
58 // ErrForkTooOld indicates a block is attempting to fork the block chain before the most recent checkpoint.
59 ErrForkTooOld
60 // ErrCheckpointTimeTooOld indicates a block has a timestamp before the most recent checkpoint.
61 ErrCheckpointTimeTooOld
62 // ErrNoTransactions indicates the block does not have a least one transaction. A valid block must have at least the
63 // coinbase transaction.
64 ErrNoTransactions
65 // ErrNoTxInputs indicates a transaction does not have any inputs. A valid transaction must have at least one input.
66 ErrNoTxInputs
67 // ErrNoTxOutputs indicates a transaction does not have any outputs. A valid transaction must have at least one
68 // output.
69 ErrNoTxOutputs
70 // ErrTxTooBig indicates a transaction exceeds the maximum allowed size when serialized.
71 ErrTxTooBig
72 // ErrBadTxOutValue indicates an output value for a transaction is invalid in some way such as being out of range.
73 ErrBadTxOutValue
74 // ErrDuplicateTxInputs indicates a transaction references the same input more than once.
75 ErrDuplicateTxInputs
76 // ErrBadTxInput indicates a transaction input is invalid in some way such as referencing a previous transaction
77 // outpoint which is out of range or not referencing one at all.
78 ErrBadTxInput
79 // ErrMissingTxOut indicates a transaction output referenced by an input either does not exist or has already been
80 // spent.
81 ErrMissingTxOut
82 // ErrUnfinalizedTx indicates a transaction has not been finalized. A valid block may only contain finalized
83 // transactions.
84 ErrUnfinalizedTx
85 // ErrDuplicateTx indicates a block contains an identical transaction (or at least two transactions which hash to
86 // the same value). A valid block may only contain unique transactions.
87 ErrDuplicateTx
88 // ErrOverwriteTx indicates a block contains a transaction that has the same hash as a previous transaction which
89 // has not been fully spent.
90 ErrOverwriteTx
91 // ErrImmatureSpend indicates a transaction is attempting to spend a coinbase that has not yet reached the required
92 // maturity.
93 ErrImmatureSpend
94 // ErrSpendTooHigh indicates a transaction is attempting to spend more value than the sum of all of its inputs.
95 ErrSpendTooHigh
96 // ErrBadFees indicates the total fees for a block are invalid due to exceeding the maximum possible value.
97 ErrBadFees
98 // ErrTooManySigOps indicates the total number of signature operations for a transaction or block exceed the maximum
99 // allowed limits.
100 ErrTooManySigOps
101 // ErrFirstTxNotCoinbase indicates the first transaction in a block is not a coinbase transaction.
102 ErrFirstTxNotCoinbase
103 // ErrMultipleCoinbases indicates a block contains more than one coinbase transaction.
104 ErrMultipleCoinbases
105 // ErrBadCoinbaseScriptLen indicates the length of the signature script for a coinbase transaction is not within the
106 // valid range.
107 ErrBadCoinbaseScriptLen
108 // ErrBadCoinbaseValue indicates the amount of a coinbase value does not match the expected value of the subsidy
109 // plus the sum of all fees.
110 ErrBadCoinbaseValue
111 // ErrMissingCoinbaseHeight indicates the coinbase transaction for a block does not start with the serialized block
112 // block height as required for version 2 and higher blocks.
113 ErrMissingCoinbaseHeight
114 // ErrBadCoinbaseHeight indicates the serialized block height in the coinbase transaction for version 2 and higher
115 // blocks does not match the expected value.
116 ErrBadCoinbaseHeight
117 // ErrScriptMalformed indicates a transaction script is malformed in some way. For example, it might be longer than
118 // the maximum allowed length or fail to parse.
119 ErrScriptMalformed
120 // ErrScriptValidation indicates the result of executing transaction script failed. The error covers any failure
121 // when executing scripts such signature verification failures and execution past the end of the stack.
122 ErrScriptValidation
123 // ErrUnexpectedWitness indicates that a block includes transactions with witness data, but doesn't also have a
124 // witness commitment within the coinbase transaction.
125 ErrUnexpectedWitness
126 // ErrInvalidWitnessCommitment indicates that a block's witness commitment is not well formed.
127 ErrInvalidWitnessCommitment
128 // ErrWitnessCommitmentMismatch indicates that the witness commitment included in the block's coinbase transaction
129 // doesn't match the manually computed witness commitment.
130 ErrWitnessCommitmentMismatch
131 // ErrPreviousBlockUnknown indicates that the previous block is not known.
132 ErrPreviousBlockUnknown
133 // ErrInvalidAncestorBlock indicates that an ancestor of this block has already failed validation.
134 ErrInvalidAncestorBlock
135 // ErrPrevBlockNotBest indicates that the block's previous block is not the current chain tip. This is not a block
136 // validation rule, but is required for block proposals submitted via getblocktemplate RPC.
137 ErrPrevBlockNotBest
138 // ErrBlacklisted indicates a transaction contains a blacklisted address
139 ErrBlacklisted
140 )
141 142 // Map of ErrorCode values back to their constant names for pretty printing.
143 var errorCodeStrings = map[ErrorCode]string{
144 ErrDuplicateBlock: "ErrDuplicateBlock",
145 ErrBlockTooBig: "ErrBlockTooBig",
146 ErrBlockVersionTooOld: "ErrBlockVersionTooOld",
147 ErrBlockWeightTooHigh: "ErrBlockWeightTooHigh",
148 ErrInvalidTime: "ErrInvalidTime",
149 ErrTimeTooOld: "ErrTimeTooOld",
150 ErrTimeTooNew: "ErrTimeTooNew",
151 ErrDifficultyTooLow: "ErrDifficultyTooLow",
152 ErrUnexpectedDifficulty: "ErrUnexpectedDifficulty",
153 ErrHighHash: "ErrHighHash",
154 ErrBadMerkleRoot: "ErrBadMerkleRoot",
155 ErrBadCheckpoint: "ErrBadCheckpoint",
156 ErrForkTooOld: "ErrForkTooOld",
157 ErrCheckpointTimeTooOld: "ErrCheckpointTimeTooOld",
158 ErrNoTransactions: "ErrNoTransactions",
159 ErrNoTxInputs: "ErrNoTxInputs",
160 ErrNoTxOutputs: "ErrNoTxOutputs",
161 ErrTxTooBig: "ErrTxTooBig",
162 ErrBadTxOutValue: "ErrBadTxOutValue",
163 ErrDuplicateTxInputs: "ErrDuplicateTxInputs",
164 ErrBadTxInput: "ErrBadTxInput",
165 ErrMissingTxOut: "ErrMissingTxOut",
166 ErrUnfinalizedTx: "ErrUnfinalizedTx",
167 ErrDuplicateTx: "ErrDuplicateTx",
168 ErrOverwriteTx: "ErrOverwriteTx",
169 ErrImmatureSpend: "ErrImmatureSpend",
170 ErrSpendTooHigh: "ErrSpendTooHigh",
171 ErrBadFees: "ErrBadFees",
172 ErrTooManySigOps: "ErrTooManySigOps",
173 ErrFirstTxNotCoinbase: "ErrFirstTxNotCoinbase",
174 ErrMultipleCoinbases: "ErrMultipleCoinbases",
175 ErrBadCoinbaseScriptLen: "ErrBadCoinbaseScriptLen",
176 ErrBadCoinbaseValue: "ErrBadCoinbaseValue",
177 ErrMissingCoinbaseHeight: "ErrMissingCoinbaseHeight",
178 ErrBadCoinbaseHeight: "ErrBadCoinbaseHeight",
179 ErrScriptMalformed: "ErrScriptMalformed",
180 ErrScriptValidation: "ErrScriptValidation",
181 ErrUnexpectedWitness: "ErrUnexpectedWitness",
182 ErrInvalidWitnessCommitment: "ErrInvalidWitnessCommitment",
183 ErrWitnessCommitmentMismatch: "ErrWitnessCommitmentMismatch",
184 ErrPreviousBlockUnknown: "ErrPreviousBlockUnknown",
185 ErrInvalidAncestorBlock: "ErrInvalidAncestorBlock",
186 ErrPrevBlockNotBest: "ErrPrevBlockNotBest",
187 }
188 189 // String returns the ErrorCode as a human-readable name.
190 func (e ErrorCode) String() string {
191 if s := errorCodeStrings[e]; s != "" {
192 return s
193 }
194 return fmt.Sprintf("Unknown ErrorCode (%d)", int(e))
195 }
196 197 // RuleError identifies a rule violation. It is used to indicate that processing of a block or transaction failed due to
198 // one of the many validation rules. The caller can use type assertions to determine if a failure was specifically due
199 // to a rule violation and access the ErrorCode field to ascertain the specific reason for the rule violation.
200 type RuleError struct {
201 ErrorCode ErrorCode // Describes the kind of error
202 Description string // Human readable description of the issue
203 }
204 205 // Error satisfies the error interface and prints human-readable errors.
206 func (e RuleError) Error() string {
207 return e.Description
208 }
209 210 // ruleError creates an RuleError given a set of arguments.
211 func ruleError(c ErrorCode, desc string) RuleError {
212 return RuleError{ErrorCode: c, Description: desc}
213 }
214