dcrd/blockchain/standalone/error.go
Dave Collins 2c7d20442e
blockchain/standalone: Implement a new module.
This implements a new module named blockchain/standalone which aims to
provide several of the standalone functions currently available in
blockchain and ultimately replace them in the next major version.

The primary goal of offering these functions via a separate module is to
reduce the required dependencies to a minimum as compared to the
blockchain module.  It will be ideal for applications such as
lightweight clients that need to ensure basic security properties hold
and calculate appropriate vote subsidies and block explorers.

For example, some things an SPV wallet needs to prove are that the block
headers all connect together, that they satisfy the proof of work
requirements, and that a given transaction tree is valid for a given
header.

The new module currently only provides functions related to proof of
work, however, future commits will provide functions for merkle root
calculation, subsidy calculation, and coinbase transaction
identification.  It is being done in stages to help ease review since it
is consensus critical code.

Finally, it also includes comprehensive tests, full package
documentation, and basic usage examples.
2019-08-06 10:29:30 -05:00

67 lines
2.1 KiB
Go

// Copyright (c) 2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package standalone
import (
"fmt"
)
// ErrorCode identifies a kind of error.
type ErrorCode int
// These constants are used to identify a specific RuleError.
const (
// ErrUnexpectedDifficulty indicates specified bits do not align with
// the expected value either because it doesn't match the calculated
// value based on difficulty rules or it is out of the valid range.
ErrUnexpectedDifficulty ErrorCode = iota
// ErrHighHash indicates the block does not hash to a value which is
// lower than the required target difficultly.
ErrHighHash
// numErrorCodes is the maximum error code number used in tests.
numErrorCodes
)
// Map of ErrorCode values back to their constant names for pretty printing.
var errorCodeStrings = map[ErrorCode]string{
ErrUnexpectedDifficulty: "ErrUnexpectedDifficulty",
ErrHighHash: "ErrHighHash",
}
// String returns the ErrorCode as a human-readable name.
func (e ErrorCode) String() string {
if s := errorCodeStrings[e]; s != "" {
return s
}
return fmt.Sprintf("Unknown ErrorCode (%d)", int(e))
}
// RuleError identifies a rule violation. The caller can use type assertions to
// determine if a failure was specifically due to a rule violation and access
// the ErrorCode field to ascertain the specific reason for the rule violation.
type RuleError struct {
ErrorCode ErrorCode // Describes the kind of error
Description string // Human readable description of the issue
}
// Error satisfies the error interface and prints human-readable errors.
func (e RuleError) Error() string {
return e.Description
}
// ruleError creates an RuleError given a set of arguments.
func ruleError(c ErrorCode, desc string) RuleError {
return RuleError{ErrorCode: c, Description: desc}
}
// IsErrorCode returns whether or not the provided error is a rule error with
// the provided error code.
func IsErrorCode(err error, c ErrorCode) bool {
e, ok := err.(RuleError)
return ok && e.ErrorCode == c
}