183 lines
6.6 KiB
Go
183 lines
6.6 KiB
Go
|
/*
|
||
|
* Copyright (c) 2014 Conformal Systems LLC <info@conformal.com>
|
||
|
*
|
||
|
* Permission to use, copy, modify, and distribute this software for any
|
||
|
* purpose with or without fee is hereby granted, provided that the above
|
||
|
* copyright notice and this permission notice appear in all copies.
|
||
|
*
|
||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||
|
*/
|
||
|
|
||
|
package waddrmgr
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"strconv"
|
||
|
|
||
|
"github.com/conformal/btcutil/hdkeychain"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
// errAlreadyExists is the common error description used for the
|
||
|
// ErrAlreadyExists error code.
|
||
|
errAlreadyExists = "the specified address manager already exists"
|
||
|
|
||
|
// errCoinTypeTooHigh is the common error description used for the
|
||
|
// ErrCoinTypeTooHigh error code.
|
||
|
errCoinTypeTooHigh = "coin type may not exceed " +
|
||
|
strconv.FormatUint(hdkeychain.HardenedKeyStart-1, 10)
|
||
|
|
||
|
// errAcctTooHigh is the common error description used for the
|
||
|
// ErrAccountNumTooHigh error code.
|
||
|
errAcctTooHigh = "account number may not exceed " +
|
||
|
strconv.FormatUint(hdkeychain.HardenedKeyStart-1, 10)
|
||
|
|
||
|
// errLocked is the common error description used for the ErrLocked
|
||
|
// error code.
|
||
|
errLocked = "address manager is locked"
|
||
|
|
||
|
// errWatchingOnly is the common error description used for the
|
||
|
// ErrWatchingOnly error code.
|
||
|
errWatchingOnly = "address manager is watching-only"
|
||
|
)
|
||
|
|
||
|
// ErrorCode identifies a kind of error.
|
||
|
type ErrorCode int
|
||
|
|
||
|
// These constants are used to identify a specific ManagerError.
|
||
|
const (
|
||
|
// ErrDatabase indicates an error with the underlying database. When
|
||
|
// this error code is set, the Err field of the ManagerError will be
|
||
|
// set to the underlying error returned from the database.
|
||
|
ErrDatabase ErrorCode = iota
|
||
|
|
||
|
// ErrKeyChain indicates an error with the key chain typically either
|
||
|
// due to the inability to create and extended key or deriving a child
|
||
|
// extended key. When this error code is set, the Err field of the
|
||
|
// ManagerError will be set to the underlying error.
|
||
|
ErrKeyChain
|
||
|
|
||
|
// ErrCrypto indicates an error with the cryptography related operations
|
||
|
// such as decrypting or encrypting data, parsing an EC public key,
|
||
|
// or deriving a secret key from a password. When this error code is
|
||
|
// set, the Err field of the ManagerError will be set to the underlying
|
||
|
// error.
|
||
|
ErrCrypto
|
||
|
|
||
|
// ErrNoExist indicates the specified database does not exist.
|
||
|
ErrNoExist
|
||
|
|
||
|
// ErrAlreadyExists indicates the specified database already exists.
|
||
|
ErrAlreadyExists
|
||
|
|
||
|
// ErrCoinTypeTooHigh indicates the coin type specified in the provided
|
||
|
// network parameters is higher than the max allowed value as defined
|
||
|
// by the maxCoinType constant.
|
||
|
ErrCoinTypeTooHigh
|
||
|
|
||
|
// ErrAccountNumTooHigh indicates the specified account number is higher
|
||
|
// than the max allowed value as defined by the MaxAccountNum constant.
|
||
|
ErrAccountNumTooHigh
|
||
|
|
||
|
// ErrLocked indicates the an operation which requires the address
|
||
|
// manager to be unlocked was requested on a locked address manager.
|
||
|
ErrLocked
|
||
|
|
||
|
// ErrWatchingOnly indicates the an operation which requires the address
|
||
|
// manager to have access to private data was requested on a
|
||
|
// watching-only address manager.
|
||
|
ErrWatchingOnly
|
||
|
|
||
|
// ErrInvalidAccount indicates the requested account is not valid.
|
||
|
ErrInvalidAccount
|
||
|
|
||
|
// ErrAddressNotFound indicates the requested address is not known to
|
||
|
// the address manager.
|
||
|
ErrAddressNotFound
|
||
|
|
||
|
// ErrAccountNotFound indicates the requested account is not known to
|
||
|
// the address manager.
|
||
|
ErrAccountNotFound
|
||
|
|
||
|
// ErrDuplicate indicates an address already exists.
|
||
|
ErrDuplicate
|
||
|
|
||
|
// ErrTooManyAddresses indicates more than the maximum allowed number of
|
||
|
// addresses per account have been requested.
|
||
|
ErrTooManyAddresses
|
||
|
|
||
|
// ErrWrongPassphrase inidicates the specified password is incorrect.
|
||
|
// This could be for either the public and private master keys.
|
||
|
ErrWrongPassphrase
|
||
|
|
||
|
// ErrWrongNet indicates the private key to be imported is not for the
|
||
|
// the same network the account mangaer is configured for.
|
||
|
ErrWrongNet
|
||
|
)
|
||
|
|
||
|
// Map of ErrorCode values back to their constant names for pretty printing.
|
||
|
var errorCodeStrings = map[ErrorCode]string{
|
||
|
ErrDatabase: "ErrDatabase",
|
||
|
ErrKeyChain: "ErrKeyChain",
|
||
|
ErrCrypto: "ErrCrypto",
|
||
|
ErrNoExist: "ErrNoExist",
|
||
|
ErrAlreadyExists: "ErrAlreadyExists",
|
||
|
ErrCoinTypeTooHigh: "ErrCoinTypeTooHigh",
|
||
|
ErrAccountNumTooHigh: "ErrAccountNumTooHigh",
|
||
|
ErrLocked: "ErrLocked",
|
||
|
ErrWatchingOnly: "ErrWatchingOnly",
|
||
|
ErrInvalidAccount: "ErrInvalidAccount",
|
||
|
ErrAddressNotFound: "ErrAddressNotFound",
|
||
|
ErrAccountNotFound: "ErrAccountNotFound",
|
||
|
ErrDuplicate: "ErrDuplicate",
|
||
|
ErrTooManyAddresses: "ErrTooManyAddresses",
|
||
|
ErrWrongPassphrase: "ErrWrongPassphrase",
|
||
|
ErrWrongNet: "ErrWrongNet",
|
||
|
}
|
||
|
|
||
|
// 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))
|
||
|
}
|
||
|
|
||
|
// ManagerError provides a single type for errors that can happen during address
|
||
|
// manager operation. It is used to indicate several types of failures
|
||
|
// including errors with caller requests such as invalid accounts or requesting
|
||
|
// private keys against a locked address manager, errors with the database
|
||
|
// (ErrDatabase), errors with key chain derivation (ErrKeyChain), and errors
|
||
|
// related to crypto (ErrCrypto).
|
||
|
//
|
||
|
// The caller can use type assertions to determine if an error is a ManagerError
|
||
|
// and access the ErrorCode field to ascertain the specific reason for the
|
||
|
// failure.
|
||
|
//
|
||
|
// The ErrDatabase, ErrKeyChain, and ErrCrypto error codes will also have the
|
||
|
// Err field set with the underlying error.
|
||
|
type ManagerError struct {
|
||
|
ErrorCode ErrorCode // Describes the kind of error
|
||
|
Description string // Human readable description of the issue
|
||
|
Err error // Underlying error
|
||
|
}
|
||
|
|
||
|
// Error satisfies the error interface and prints human-readable errors.
|
||
|
func (e ManagerError) Error() string {
|
||
|
if e.Err != nil {
|
||
|
return e.Description + ": " + e.Err.Error()
|
||
|
}
|
||
|
return e.Description
|
||
|
}
|
||
|
|
||
|
// managerError creates a ManagerError given a set of arguments.
|
||
|
func managerError(c ErrorCode, desc string, err error) ManagerError {
|
||
|
return ManagerError{ErrorCode: c, Description: desc, Err: err}
|
||
|
}
|