This commit is contained in:
Emmanuel T Odeke 2017-09-22 08:23:25 +00:00 committed by GitHub
commit 5ac1b8436b
46 changed files with 322 additions and 113 deletions

View file

@ -18,6 +18,7 @@ package abi
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io" "io"
"reflect" "reflect"
@ -85,12 +86,16 @@ var (
r_byte = reflect.TypeOf(byte(0)) r_byte = reflect.TypeOf(byte(0))
) )
var (
errEmptyABIOutput = errors.New("abi: unmarshalling empty output")
)
// Unpack output in v according to the abi specification // Unpack output in v according to the abi specification
func (abi ABI) Unpack(v interface{}, name string, output []byte) error { func (abi ABI) Unpack(v interface{}, name string, output []byte) error {
var method = abi.Methods[name] var method = abi.Methods[name]
if len(output) == 0 { if len(output) == 0 {
return fmt.Errorf("abi: unmarshalling empty output") return errEmptyABIOutput
} }
// make sure the passed value is a pointer // make sure the passed value is a pointer

View file

@ -18,7 +18,7 @@ package bind
import ( import (
"context" "context"
"fmt" "errors"
"time" "time"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -52,18 +52,23 @@ func WaitMined(ctx context.Context, b DeployBackend, tx *types.Transaction) (*ty
} }
} }
var (
errTxNotContractCreation = errors.New("tx is not contract creation")
errZeroAddress = errors.New("zero address")
)
// WaitDeployed waits for a contract deployment transaction and returns the on-chain // WaitDeployed waits for a contract deployment transaction and returns the on-chain
// contract address when it is mined. It stops waiting when ctx is canceled. // contract address when it is mined. It stops waiting when ctx is canceled.
func WaitDeployed(ctx context.Context, b DeployBackend, tx *types.Transaction) (common.Address, error) { func WaitDeployed(ctx context.Context, b DeployBackend, tx *types.Transaction) (common.Address, error) {
if tx.To() != nil { if tx.To() != nil {
return common.Address{}, fmt.Errorf("tx is not contract creation") return common.Address{}, errTxNotContractCreation
} }
receipt, err := WaitMined(ctx, b, tx) receipt, err := WaitMined(ctx, b, tx)
if err != nil { if err != nil {
return common.Address{}, err return common.Address{}, err
} }
if receipt.ContractAddress == (common.Address{}) { if receipt.ContractAddress == (common.Address{}) {
return common.Address{}, fmt.Errorf("zero address") return common.Address{}, errZeroAddress
} }
// Check that code has indeed been deployed at the address. // Check that code has indeed been deployed at the address.
// This matters on pre-Homestead chains: OOG in the constructor // This matters on pre-Homestead chains: OOG in the constructor

View file

@ -18,6 +18,7 @@ package abi
import ( import (
"encoding/binary" "encoding/binary"
"errors"
"fmt" "fmt"
"math/big" "math/big"
"reflect" "reflect"
@ -160,9 +161,11 @@ func readInteger(kind reflect.Kind, b []byte) interface{} {
} }
} }
var errIncorrectWordLength = errors.New("abi: fatal error: incorrect word length")
func readBool(word []byte) (bool, error) { func readBool(word []byte) (bool, error) {
if len(word) != 32 { if len(word) != 32 {
return false, fmt.Errorf("abi: fatal error: incorrect word length") return false, errIncorrectWordLength
} }
for i, b := range word { for i, b := range word {

View file

@ -24,7 +24,6 @@ import (
"crypto/ecdsa" "crypto/ecdsa"
crand "crypto/rand" crand "crypto/rand"
"errors" "errors"
"fmt"
"math/big" "math/big"
"os" "os"
"path/filepath" "path/filepath"
@ -44,6 +43,8 @@ var (
ErrLocked = accounts.NewAuthNeededError("password or unlock") ErrLocked = accounts.NewAuthNeededError("password or unlock")
ErrNoMatch = errors.New("no key for given address or file") ErrNoMatch = errors.New("no key for given address or file")
ErrDecrypt = errors.New("could not decrypt key with given passphrase") ErrDecrypt = errors.New("could not decrypt key with given passphrase")
errAccountExists = errors.New("account already exists")
) )
// KeyStoreType is the reflect type of a keystore backend. // KeyStoreType is the reflect type of a keystore backend.
@ -448,7 +449,7 @@ func (ks *KeyStore) Import(keyJSON []byte, passphrase, newPassphrase string) (ac
func (ks *KeyStore) ImportECDSA(priv *ecdsa.PrivateKey, passphrase string) (accounts.Account, error) { func (ks *KeyStore) ImportECDSA(priv *ecdsa.PrivateKey, passphrase string) (accounts.Account, error) {
key := newKeyFromECDSA(priv) key := newKeyFromECDSA(priv)
if ks.cache.hasAddress(key.Address) { if ks.cache.hasAddress(key.Address) {
return accounts.Account{}, fmt.Errorf("account already exists") return accounts.Account{}, errAccountExists
} }
return ks.importKey(key, passphrase) return ks.importKey(key, passphrase)
} }

View file

@ -19,6 +19,7 @@ package utils
import ( import (
"compress/gzip" "compress/gzip"
"errors"
"fmt" "fmt"
"io" "io"
"os" "os"
@ -80,6 +81,8 @@ func StartNode(stack *node.Node) {
}() }()
} }
var errInterrupted = errors.New("interrupted")
func ImportChain(chain *core.BlockChain, fn string) error { func ImportChain(chain *core.BlockChain, fn string) error {
// Watch for Ctrl-C while the import is running. // Watch for Ctrl-C while the import is running.
// If a signal is received, the import will stop at the next batch. // If a signal is received, the import will stop at the next batch.
@ -125,7 +128,7 @@ func ImportChain(chain *core.BlockChain, fn string) error {
for batch := 0; ; batch++ { for batch := 0; ; batch++ {
// Load a batch of RLP blocks. // Load a batch of RLP blocks.
if checkInterrupt() { if checkInterrupt() {
return fmt.Errorf("interrupted") return errInterrupted
} }
i := 0 i := 0
for ; i < importBatchSize; i++ { for ; i < importBatchSize; i++ {
@ -148,7 +151,7 @@ func ImportChain(chain *core.BlockChain, fn string) error {
} }
// Import the batch. // Import the batch.
if checkInterrupt() { if checkInterrupt() {
return fmt.Errorf("interrupted") return errInterrupted
} }
if hasAllBlocks(chain, blocks[:i]) { if hasAllBlocks(chain, blocks[:i]) {
log.Info("Skipping batch as all blocks present", "batch", batch, "first", blocks[0].Hash(), "last", blocks[i-1].Hash()) log.Info("Skipping batch as all blocks present", "batch", batch, "first", blocks[0].Hash(), "last", blocks[i-1].Hash())

View file

@ -29,6 +29,7 @@ import (
"context" "context"
"crypto/ecdsa" "crypto/ecdsa"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"math/big" "math/big"
@ -443,11 +444,16 @@ type Inbox struct {
log log.Logger // contextual logger with the contract address embedded log log.Logger // contextual logger with the contract address embedded
} }
var (
errNilSigner = errors.New("signer is null")
errInvalidAmount = errors.New("invalid amount")
)
// NewInbox creates an Inbox. An Inboxes is not persisted, the cumulative sum is updated // NewInbox creates an Inbox. An Inboxes is not persisted, the cumulative sum is updated
// from blockchain when first cheque is received. // from blockchain when first cheque is received.
func NewInbox(prvKey *ecdsa.PrivateKey, contractAddr, beneficiary common.Address, signer *ecdsa.PublicKey, abigen bind.ContractBackend) (self *Inbox, err error) { func NewInbox(prvKey *ecdsa.PrivateKey, contractAddr, beneficiary common.Address, signer *ecdsa.PublicKey, abigen bind.ContractBackend) (self *Inbox, err error) {
if signer == nil { if signer == nil {
return nil, fmt.Errorf("signer is null") return nil, errNilSigner
} }
chbook, err := contract.NewChequebook(contractAddr, abigen) chbook, err := contract.NewChequebook(contractAddr, abigen)
if err != nil { if err != nil {
@ -584,7 +590,7 @@ func (self *Inbox) Receive(promise swap.Promise) (*big.Int, error) {
func (self *Cheque) Verify(signerKey *ecdsa.PublicKey, contract, beneficiary common.Address, sum *big.Int) (*big.Int, error) { func (self *Cheque) Verify(signerKey *ecdsa.PublicKey, contract, beneficiary common.Address, sum *big.Int) (*big.Int, error) {
log.Trace("Verifying chequebook cheque", "cheque", self, "sum", sum) log.Trace("Verifying chequebook cheque", "cheque", self, "sum", sum)
if sum == nil { if sum == nil {
return nil, fmt.Errorf("invalid amount") return nil, errInvalidAmount
} }
if self.Beneficiary != beneficiary { if self.Beneficiary != beneficiary {

View file

@ -1062,6 +1062,11 @@ func countTransactions(chain []*types.Block) (c int) {
return c return c
} }
var (
errInvalidOldChain = errors.New("Invalid old chain")
errInvalidNewChain = errors.New("Invalid new chain")
)
// reorgs takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them // reorgs takes two blocks, an old chain and a new chain and will reconstruct the blocks and inserts them
// to be part of the new canonical chain and accumulates potential missing transactions and post an // to be part of the new canonical chain and accumulates potential missing transactions and post an
// event about them // event about them
@ -1104,10 +1109,10 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
} }
} }
if oldBlock == nil { if oldBlock == nil {
return fmt.Errorf("Invalid old chain") return errInvalidOldChain
} }
if newBlock == nil { if newBlock == nil {
return fmt.Errorf("Invalid new chain") return errInvalidNewChain
} }
for { for {
@ -1123,10 +1128,10 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
oldBlock, newBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1), bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1) oldBlock, newBlock = bc.GetBlock(oldBlock.ParentHash(), oldBlock.NumberU64()-1), bc.GetBlock(newBlock.ParentHash(), newBlock.NumberU64()-1)
if oldBlock == nil { if oldBlock == nil {
return fmt.Errorf("Invalid old chain") return errInvalidOldChain
} }
if newBlock == nil { if newBlock == nil {
return fmt.Errorf("Invalid new chain") return errInvalidNewChain
} }
} }
// Ensure the user sees large reorgs // Ensure the user sees large reorgs

View file

@ -18,6 +18,7 @@ package core
import ( import (
"encoding/binary" "encoding/binary"
"errors"
"fmt" "fmt"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -303,6 +304,10 @@ func (c *ChainIndexer) updateLoop() {
} }
} }
var (
errChainReorgedInProcessing = errors.New("chain reorged during section processing")
)
// processSection processes an entire section by calling backend functions while // processSection processes an entire section by calling backend functions while
// ensuring the continuity of the passed headers. Since the chain mutex is not // ensuring the continuity of the passed headers. Since the chain mutex is not
// held while processing, the continuity can be broken by a long reorg, in which // held while processing, the continuity can be broken by a long reorg, in which
@ -322,7 +327,7 @@ func (c *ChainIndexer) processSection(section uint64, lastHead common.Hash) (com
if header == nil { if header == nil {
return common.Hash{}, fmt.Errorf("block #%d [%x…] not found", number, hash[:4]) return common.Hash{}, fmt.Errorf("block #%d [%x…] not found", number, hash[:4])
} else if header.ParentHash != lastHead { } else if header.ParentHash != lastHead {
return common.Hash{}, fmt.Errorf("chain reorged during section processing") return common.Hash{}, errChainReorgedInProcessing
} }
c.backend.Process(header) c.backend.Process(header)
lastHead = header.Hash() lastHead = header.Hash()

View file

@ -39,7 +39,11 @@ import (
//go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go //go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go
//go:generate gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go //go:generate gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go
var errGenesisNoConfig = errors.New("genesis has no chain configuration") var (
errGenesisNoConfig = errors.New("genesis has no chain configuration")
errMissingHeaderHashBlockNumber = errors.New("missing block number for head header hash")
errGenesisBlockNumberNonZero = errors.New("can't commit genesis block with number > 0")
)
// Genesis specifies the header fields, state of a genesis block. It also defines hard // Genesis specifies the header fields, state of a genesis block. It also defines hard
// fork switch-over blocks through the chain configuration. // fork switch-over blocks through the chain configuration.
@ -198,7 +202,7 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig
// are returned to the caller unless we're already at block zero. // are returned to the caller unless we're already at block zero.
height := GetBlockNumber(db, GetHeadHeaderHash(db)) height := GetBlockNumber(db, GetHeadHeaderHash(db))
if height == missingNumber { if height == missingNumber {
return newcfg, stored, fmt.Errorf("missing block number for head header hash") return newcfg, stored, errMissingHeaderHashBlockNumber
} }
compatErr := storedcfg.CheckCompatible(newcfg, height) compatErr := storedcfg.CheckCompatible(newcfg, height)
if compatErr != nil && height != 0 && compatErr.RewindTo != 0 { if compatErr != nil && height != 0 && compatErr.RewindTo != 0 {
@ -260,7 +264,7 @@ func (g *Genesis) ToBlock() (*types.Block, *state.StateDB) {
func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) { func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
block, statedb := g.ToBlock() block, statedb := g.ToBlock()
if block.Number().Sign() != 0 { if block.Number().Sign() != 0 {
return nil, fmt.Errorf("can't commit genesis block with number > 0") return nil, errGenesisBlockNumberNonZero
} }
if _, err := statedb.CommitTo(db, false); err != nil { if _, err := statedb.CommitTo(db, false); err != nil {
return nil, fmt.Errorf("cannot write state: %v", err) return nil, fmt.Errorf("cannot write state: %v", err)

View file

@ -35,6 +35,7 @@ import (
"crypto/elliptic" "crypto/elliptic"
"crypto/hmac" "crypto/hmac"
"crypto/subtle" "crypto/subtle"
"errors"
"fmt" "fmt"
"hash" "hash"
"io" "io"
@ -42,12 +43,12 @@ import (
) )
var ( var (
ErrImport = fmt.Errorf("ecies: failed to import key") ErrImport = errors.New("ecies: failed to import key")
ErrInvalidCurve = fmt.Errorf("ecies: invalid elliptic curve") ErrInvalidCurve = errors.New("ecies: invalid elliptic curve")
ErrInvalidParams = fmt.Errorf("ecies: invalid ECIES parameters") ErrInvalidParams = errors.New("ecies: invalid ECIES parameters")
ErrInvalidPublicKey = fmt.Errorf("ecies: invalid public key") ErrInvalidPublicKey = errors.New("ecies: invalid public key")
ErrSharedKeyIsPointAtInfinity = fmt.Errorf("ecies: shared key is point at infinity") ErrSharedKeyIsPointAtInfinity = errors.New("ecies: shared key is point at infinity")
ErrSharedKeyTooBig = fmt.Errorf("ecies: shared key params are too big") ErrSharedKeyTooBig = errors.New("ecies: shared key params are too big")
) )
// PublicKey is a representation of an elliptic curve public key. // PublicKey is a representation of an elliptic curve public key.
@ -138,9 +139,9 @@ func (prv *PrivateKey) GenerateShared(pub *PublicKey, skLen, macLen int) (sk []b
} }
var ( var (
ErrKeyDataTooLong = fmt.Errorf("ecies: can't supply requested key data") ErrKeyDataTooLong = errors.New("ecies: can't supply requested key data")
ErrSharedTooLong = fmt.Errorf("ecies: shared secret is too long") ErrSharedTooLong = errors.New("ecies: shared secret is too long")
ErrInvalidMessage = fmt.Errorf("ecies: invalid message") ErrInvalidMessage = errors.New("ecies: invalid message")
) )
var ( var (

View file

@ -39,7 +39,7 @@ import (
"crypto/elliptic" "crypto/elliptic"
"crypto/sha256" "crypto/sha256"
"crypto/sha512" "crypto/sha512"
"fmt" "errors"
"hash" "hash"
ethcrypto "github.com/ethereum/go-ethereum/crypto" ethcrypto "github.com/ethereum/go-ethereum/crypto"
@ -47,8 +47,8 @@ import (
var ( var (
DefaultCurve = ethcrypto.S256() DefaultCurve = ethcrypto.S256()
ErrUnsupportedECDHAlgorithm = fmt.Errorf("ecies: unsupported ECDH algorithm") ErrUnsupportedECDHAlgorithm = errors.New("ecies: unsupported ECDH algorithm")
ErrUnsupportedECIESParameters = fmt.Errorf("ecies: unsupported ECIES parameters") ErrUnsupportedECIESParameters = errors.New("ecies: unsupported ECIES parameters")
) )
type ECIESParams struct { type ECIESParams struct {

View file

@ -45,6 +45,10 @@ func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) {
return (*ecdsa.PublicKey)(pub), err return (*ecdsa.PublicKey)(pub), err
} }
var (
errPrivKeyCurveNotSecp256k1 = errors.New("private key curve is not secp256k1")
)
// Sign calculates an ECDSA signature. // Sign calculates an ECDSA signature.
// //
// This function is susceptible to chosen plaintext attacks that can leak // This function is susceptible to chosen plaintext attacks that can leak
@ -58,7 +62,7 @@ func Sign(hash []byte, prv *ecdsa.PrivateKey) ([]byte, error) {
return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash)) return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash))
} }
if prv.Curve != btcec.S256() { if prv.Curve != btcec.S256() {
return nil, fmt.Errorf("private key curve is not secp256k1") return nil, errPrivKeyCurveNotSecp256k1
} }
sig, err := btcec.SignCompact(btcec.S256(), (*btcec.PrivateKey)(prv), hash, false) sig, err := btcec.SignCompact(btcec.S256(), (*btcec.PrivateKey)(prv), hash, false)
if err != nil { if err != nil {

View file

@ -292,6 +292,10 @@ func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) {
s.blockchain.ResetWithGenesisBlock(gb) s.blockchain.ResetWithGenesisBlock(gb)
} }
var (
errEtherbaseAddressWanted = errors.New("etherbase address must be explicitly specified")
)
func (s *Ethereum) Etherbase() (eb common.Address, err error) { func (s *Ethereum) Etherbase() (eb common.Address, err error) {
s.lock.RLock() s.lock.RLock()
etherbase := s.etherbase etherbase := s.etherbase
@ -305,7 +309,7 @@ func (s *Ethereum) Etherbase() (eb common.Address, err error) {
return accounts[0].Address, nil return accounts[0].Address, nil
} }
} }
return common.Address{}, fmt.Errorf("etherbase address must be explicitly specified") return common.Address{}, errEtherbaseAddressWanted
} }
// set in js console via admin interface or wrapper from cli flags // set in js console via admin interface or wrapper from cli flags

View file

@ -357,6 +357,11 @@ func (api *PublicFilterAPI) UninstallFilter(id rpc.ID) bool {
return found return found
} }
var (
errFilterNotFound = errors.New("filter not found")
errInvalidTopics = errors.New("invalid topic(s)")
)
// GetFilterLogs returns the logs for the filter with the given id. // GetFilterLogs returns the logs for the filter with the given id.
// If the filter could not be found an empty array of logs is returned. // If the filter could not be found an empty array of logs is returned.
// //
@ -367,7 +372,7 @@ func (api *PublicFilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*ty
api.filtersMu.Unlock() api.filtersMu.Unlock()
if !found || f.typ != LogsSubscription { if !found || f.typ != LogsSubscription {
return nil, fmt.Errorf("filter not found") return nil, errFilterNotFound
} }
begin := rpc.LatestBlockNumber.Int64() begin := rpc.LatestBlockNumber.Int64()
@ -419,7 +424,7 @@ func (api *PublicFilterAPI) GetFilterChanges(id rpc.ID) (interface{}, error) {
} }
} }
return []interface{}{}, fmt.Errorf("filter not found") return []interface{}{}, errFilterNotFound
} }
// returnHashes is a helper that will return an empty hash array case the given hash array is nil, // returnHashes is a helper that will return an empty hash array case the given hash array is nil,
@ -519,11 +524,11 @@ func (args *FilterCriteria) UnmarshalJSON(data []byte) error {
} }
args.Topics[i] = append(args.Topics[i], parsed) args.Topics[i] = append(args.Topics[i], parsed)
} else { } else {
return fmt.Errorf("invalid topic(s)") return errInvalidTopics
} }
} }
default: default:
return fmt.Errorf("invalid topic(s)") return errInvalidTopics
} }
} }
} }

View file

@ -21,7 +21,6 @@ package filters
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"sync" "sync"
"time" "time"
@ -69,6 +68,8 @@ const (
var ( var (
ErrInvalidSubscriptionID = errors.New("invalid id") ErrInvalidSubscriptionID = errors.New("invalid id")
errInvalidFromToBlockCombination = errors.New("invalid from and to block combination: from > to")
) )
type subscription struct { type subscription struct {
@ -195,7 +196,7 @@ func (es *EventSystem) SubscribeLogs(crit FilterCriteria, logs chan []*types.Log
if from >= 0 && to == rpc.LatestBlockNumber { if from >= 0 && to == rpc.LatestBlockNumber {
return es.subscribeLogs(crit, logs), nil return es.subscribeLogs(crit, logs), nil
} }
return nil, fmt.Errorf("invalid from and to block combination: from > to") return nil, errInvalidFromToBlockCombination
} }
// subscribeMinedPendingLogs creates a subscription that returned mined and // subscribeMinedPendingLogs creates a subscription that returned mined and

View file

@ -20,6 +20,7 @@ package ethclient
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"math/big" "math/big"
@ -94,16 +95,16 @@ func (ec *Client) getBlock(ctx context.Context, method string, args ...interface
} }
// Quick-verify transaction and uncle lists. This mostly helps with debugging the server. // Quick-verify transaction and uncle lists. This mostly helps with debugging the server.
if head.UncleHash == types.EmptyUncleHash && len(body.UncleHashes) > 0 { if head.UncleHash == types.EmptyUncleHash && len(body.UncleHashes) > 0 {
return nil, fmt.Errorf("server returned non-empty uncle list but block header indicates no uncles") return nil, errServerUnexpectedNonEmptyUncles
} }
if head.UncleHash != types.EmptyUncleHash && len(body.UncleHashes) == 0 { if head.UncleHash != types.EmptyUncleHash && len(body.UncleHashes) == 0 {
return nil, fmt.Errorf("server returned empty uncle list but block header indicates uncles") return nil, errServerUnexpectedEmptyUncles
} }
if head.TxHash == types.EmptyRootHash && len(body.Transactions) > 0 { if head.TxHash == types.EmptyRootHash && len(body.Transactions) > 0 {
return nil, fmt.Errorf("server returned non-empty transaction list but block header indicates no transactions") return nil, errServerUnexpectedNonEmptyTransactions
} }
if head.TxHash != types.EmptyRootHash && len(body.Transactions) == 0 { if head.TxHash != types.EmptyRootHash && len(body.Transactions) == 0 {
return nil, fmt.Errorf("server returned empty transaction list but block header indicates transactions") return nil, errServerUnexpectedEmptyTransactions
} }
// Load uncles because they are not included in the block response. // Load uncles because they are not included in the block response.
var uncles []*types.Header var uncles []*types.Header
@ -153,6 +154,14 @@ func (ec *Client) HeaderByNumber(ctx context.Context, number *big.Int) (*types.H
return head, err return head, err
} }
var (
errServerTxWithoutSignature = errors.New("server returned transaction without signature")
errServerUnexpectedNonEmptyUncles = errors.New("server returned non-empty uncle list but block header indicates no uncles")
errServerUnexpectedEmptyUncles = errors.New("server returned empty uncle list but block header indicates uncles")
errServerUnexpectedNonEmptyTransactions = errors.New("server returned non-empty transaction list but block header indicates no transactions")
errServerUnexpectedEmptyTransactions = errors.New("server returned empty transaction list but block header indicates transactions")
)
// TransactionByHash returns the transaction with the given hash. // TransactionByHash returns the transaction with the given hash.
func (ec *Client) TransactionByHash(ctx context.Context, hash common.Hash) (tx *types.Transaction, isPending bool, err error) { func (ec *Client) TransactionByHash(ctx context.Context, hash common.Hash) (tx *types.Transaction, isPending bool, err error) {
var raw json.RawMessage var raw json.RawMessage
@ -165,7 +174,7 @@ func (ec *Client) TransactionByHash(ctx context.Context, hash common.Hash) (tx *
if err := json.Unmarshal(raw, &tx); err != nil { if err := json.Unmarshal(raw, &tx); err != nil {
return nil, false, err return nil, false, err
} else if _, r, _ := tx.RawSignatureValues(); r == nil { } else if _, r, _ := tx.RawSignatureValues(); r == nil {
return nil, false, fmt.Errorf("server returned transaction without signature") return nil, false, errServerTxWithoutSignature
} }
var block struct{ BlockNumber *string } var block struct{ BlockNumber *string }
if err := json.Unmarshal(raw, &block); err != nil { if err := json.Unmarshal(raw, &block); err != nil {
@ -189,7 +198,7 @@ func (ec *Client) TransactionInBlock(ctx context.Context, blockHash common.Hash,
if tx == nil { if tx == nil {
return nil, ethereum.NotFound return nil, ethereum.NotFound
} else if _, r, _ := tx.RawSignatureValues(); r == nil { } else if _, r, _ := tx.RawSignatureValues(); r == nil {
return nil, fmt.Errorf("server returned transaction without signature") return nil, errServerTxWithoutSignature
} }
} }
return tx, err return tx, err

View file

@ -20,6 +20,7 @@ import (
"archive/tar" "archive/tar"
"archive/zip" "archive/zip"
"compress/gzip" "compress/gzip"
"errors"
"fmt" "fmt"
"io" "io"
"os" "os"
@ -73,6 +74,10 @@ func AddFile(a Archive, file string) error {
return nil return nil
} }
var (
errUnknownArchiveExtension = errors.New("unknown archive extension")
)
// WriteArchive creates an archive containing the given files. // WriteArchive creates an archive containing the given files.
func WriteArchive(name string, files []string) (err error) { func WriteArchive(name string, files []string) (err error) {
archfd, err := os.Create(name) archfd, err := os.Create(name)
@ -89,7 +94,7 @@ func WriteArchive(name string, files []string) (err error) {
}() }()
archive, basename := NewArchive(archfd) archive, basename := NewArchive(archfd)
if archive == nil { if archive == nil {
return fmt.Errorf("unknown archive extension") return errUnknownArchiveExtension
} }
fmt.Println(name) fmt.Println(name)
if err := archive.Directory(basename); err != nil { if err := archive.Directory(basename); err != nil {

View file

@ -408,6 +408,15 @@ func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr c
return signature, nil return signature, nil
} }
var (
err65ByteSignatureWanted = errors.New("signature must be 65 bytes long")
errEthereumSignature27or28Wanted = errors.New("invalid Ethereum signature (V is not 27 or 28)")
errMissingTxNonceInSpec = errors.New("missing transaction nonce in transaction spec")
errChainDBCompactNotForMemoryDB = errors.New("chaindbCompact does not work for memory databases")
errChainDBPropertyNotForMemoryDB = errors.New("chaindbProperty does not work for memory databases")
)
// EcRecover returns the address for the account that was used to create the signature. // EcRecover returns the address for the account that was used to create the signature.
// Note, this function is compatible with eth_sign and personal_sign. As such it recovers // Note, this function is compatible with eth_sign and personal_sign. As such it recovers
// the address of: // the address of:
@ -420,10 +429,10 @@ func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr c
// https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_ecRecover // https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_ecRecover
func (s *PrivateAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) { func (s *PrivateAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) {
if len(sig) != 65 { if len(sig) != 65 {
return common.Address{}, fmt.Errorf("signature must be 65 bytes long") return common.Address{}, err65ByteSignatureWanted
} }
if sig[64] != 27 && sig[64] != 28 { if sig[64] != 27 && sig[64] != 28 {
return common.Address{}, fmt.Errorf("invalid Ethereum signature (V is not 27 or 28)") return common.Address{}, errEthereumSignature27or28Wanted
} }
sig[64] -= 27 // Transform yellow paper V from 27/28 to 0/1 sig[64] -= 27 // Transform yellow paper V from 27/28 to 0/1
@ -1235,7 +1244,7 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, err
// the given transaction from the pool and reinsert it with the new gas price and limit. // the given transaction from the pool and reinsert it with the new gas price and limit.
func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxArgs, gasPrice, gasLimit *hexutil.Big) (common.Hash, error) { func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxArgs, gasPrice, gasLimit *hexutil.Big) (common.Hash, error) {
if sendArgs.Nonce == nil { if sendArgs.Nonce == nil {
return common.Hash{}, fmt.Errorf("missing transaction nonce in transaction spec") return common.Hash{}, errMissingTxNonceInSpec
} }
if err := sendArgs.setDefaults(ctx, s.b); err != nil { if err := sendArgs.setDefaults(ctx, s.b); err != nil {
return common.Hash{}, err return common.Hash{}, err
@ -1336,7 +1345,7 @@ func (api *PrivateDebugAPI) ChaindbProperty(property string) (string, error) {
LDB() *leveldb.DB LDB() *leveldb.DB
}) })
if !ok { if !ok {
return "", fmt.Errorf("chaindbProperty does not work for memory databases") return "", errChainDBPropertyNotForMemoryDB
} }
if property == "" { if property == "" {
property = "leveldb.stats" property = "leveldb.stats"
@ -1351,7 +1360,7 @@ func (api *PrivateDebugAPI) ChaindbCompact() error {
LDB() *leveldb.DB LDB() *leveldb.DB
}) })
if !ok { if !ok {
return fmt.Errorf("chaindbCompact does not work for memory databases") return errChainDBCompactNotForMemoryDB
} }
for b := byte(0); b < 255; b++ { for b := byte(0); b < 255; b++ {
log.Info("Compacting chain database", "range", fmt.Sprintf("0x%0.2X-0x%0.2X", b, b+1)) log.Info("Compacting chain database", "range", fmt.Sprintf("0x%0.2X-0x%0.2X", b, b+1))

View file

@ -215,6 +215,11 @@ type JavascriptTracer struct {
err error // Error, if one has occurred err error // Error, if one has occurred
} }
var (
errTraceMustExposeFunctionStep = errors.New("Trace object must expose a function step()")
errTraceMustExposeFunctionResult = errors.New("Trace object must expose a function result()")
)
// NewJavascriptTracer instantiates a new JavascriptTracer instance. // NewJavascriptTracer instantiates a new JavascriptTracer instance.
// code specifies a Javascript snippet, which must evaluate to an expression // code specifies a Javascript snippet, which must evaluate to an expression
// returning an object with 'step' and 'result' functions. // returning an object with 'step' and 'result' functions.
@ -237,7 +242,7 @@ func NewJavascriptTracer(code string) (*JavascriptTracer, error) {
return nil, err return nil, err
} }
if !step.IsFunction() { if !step.IsFunction() {
return nil, fmt.Errorf("Trace object must expose a function step()") return nil, errTraceMustExposeFunctionStep
} }
result, err := jstracer.Get("result") result, err := jstracer.Get("result")
@ -245,7 +250,7 @@ func NewJavascriptTracer(code string) (*JavascriptTracer, error) {
return nil, err return nil, err
} }
if !result.IsFunction() { if !result.IsFunction() {
return nil, fmt.Errorf("Trace object must expose a function result()") return nil, errTraceMustExposeFunctionResult
} }
// Create the persistent log object // Create the persistent log object

View file

@ -18,7 +18,7 @@
package les package les
import ( import (
"fmt" "errors"
"sync" "sync"
"time" "time"
@ -132,14 +132,16 @@ func lesTopic(genesisHash common.Hash) discv5.Topic {
type LightDummyAPI struct{} type LightDummyAPI struct{}
var errNotSupported = errors.New("not supported")
// Etherbase is the address that mining rewards will be send to // Etherbase is the address that mining rewards will be send to
func (s *LightDummyAPI) Etherbase() (common.Address, error) { func (s *LightDummyAPI) Etherbase() (common.Address, error) {
return common.Address{}, fmt.Errorf("not supported") return common.Address{}, errNotSupported
} }
// Coinbase is the address that mining rewards will be send to (alias for Etherbase) // Coinbase is the address that mining rewards will be send to (alias for Etherbase)
func (s *LightDummyAPI) Coinbase() (common.Address, error) { func (s *LightDummyAPI) Coinbase() (common.Address, error) {
return common.Address{}, fmt.Errorf("not supported") return common.Address{}, errNotSupported
} }
// Hashrate returns the POW hashrate // Hashrate returns the POW hashrate

View file

@ -18,6 +18,7 @@ package miner
import ( import (
"bytes" "bytes"
"errors"
"fmt" "fmt"
"math/big" "math/big"
"sync" "sync"
@ -487,10 +488,14 @@ func (self *worker) commitNewWork() {
self.push(work) self.push(work)
} }
var (
errUncleNotUnique = errors.New("uncle not unique")
)
func (self *worker) commitUncle(work *Work, uncle *types.Header) error { func (self *worker) commitUncle(work *Work, uncle *types.Header) error {
hash := uncle.Hash() hash := uncle.Hash()
if work.uncles.Has(hash) { if work.uncles.Has(hash) {
return fmt.Errorf("uncle not unique") return errUncleNotUnique
} }
if !work.ancestors.Has(uncle.ParentHash) { if !work.ancestors.Has(uncle.ParentHash) {
return fmt.Errorf("uncle's parent unknown (%x)", uncle.ParentHash[0:4]) return fmt.Errorf("uncle's parent unknown (%x)", uncle.ParentHash[0:4])

View file

@ -17,6 +17,7 @@
package node package node
import ( import (
"errors"
"fmt" "fmt"
"strings" "strings"
"time" "time"
@ -115,13 +116,18 @@ func (api *PrivateAdminAPI) StartRPC(host *string, port *int, cors *string, apis
return true, nil return true, nil
} }
var (
errHTTPRPCNotRunning = errors.New("HTTP RPC not running")
errWebsocketRPCNotRunning = errors.New("WebSocket RPC not running")
)
// StopRPC terminates an already running HTTP RPC API endpoint. // StopRPC terminates an already running HTTP RPC API endpoint.
func (api *PrivateAdminAPI) StopRPC() (bool, error) { func (api *PrivateAdminAPI) StopRPC() (bool, error) {
api.node.lock.Lock() api.node.lock.Lock()
defer api.node.lock.Unlock() defer api.node.lock.Unlock()
if api.node.httpHandler == nil { if api.node.httpHandler == nil {
return false, fmt.Errorf("HTTP RPC not running") return false, errHTTPRPCNotRunning
} }
api.node.stopHTTP() api.node.stopHTTP()
return true, nil return true, nil
@ -175,7 +181,7 @@ func (api *PrivateAdminAPI) StopWS() (bool, error) {
defer api.node.lock.Unlock() defer api.node.lock.Unlock()
if api.node.wsHandler == nil { if api.node.wsHandler == nil {
return false, fmt.Errorf("WebSocket RPC not running") return false, errWebsocketRPCNotRunning
} }
api.node.stopWS() api.node.stopWS()
return true, nil return true, nil

View file

@ -1052,6 +1052,10 @@ func (net *Network) handle(n *Node, ev nodeEvent, pkt *ingressPacket) error {
return err return err
} }
var (
errPongReplyMismatch = errors.New("pong reply token mismatch")
)
func (net *Network) checkPacket(n *Node, ev nodeEvent, pkt *ingressPacket) error { func (net *Network) checkPacket(n *Node, ev nodeEvent, pkt *ingressPacket) error {
// Replay prevention checks. // Replay prevention checks.
switch ev { switch ev {
@ -1061,7 +1065,7 @@ func (net *Network) checkPacket(n *Node, ev nodeEvent, pkt *ingressPacket) error
case pongPacket: case pongPacket:
if !bytes.Equal(pkt.data.(*pong).ReplyTok, n.pingEcho) { if !bytes.Equal(pkt.data.(*pong).ReplyTok, n.pingEcho) {
// fmt.Println("pong reply token mismatch") // fmt.Println("pong reply token mismatch")
return fmt.Errorf("pong reply token mismatch") return errPongReplyMismatch
} }
n.pingEcho = nil n.pingEcho = nil
} }

View file

@ -19,6 +19,7 @@ package discv5
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"errors"
"fmt" "fmt"
"math" "math"
"math/rand" "math/rand"
@ -88,13 +89,15 @@ func (ref ticketRef) topicRegTime() mclock.AbsTime {
return ref.t.regTime[ref.idx] return ref.t.regTime[ref.idx]
} }
var errBadTopicHash = errors.New("bad topic hash")
func pongToTicket(localTime mclock.AbsTime, topics []Topic, node *Node, p *ingressPacket) (*ticket, error) { func pongToTicket(localTime mclock.AbsTime, topics []Topic, node *Node, p *ingressPacket) (*ticket, error) {
wps := p.data.(*pong).WaitPeriods wps := p.data.(*pong).WaitPeriods
if len(topics) != len(wps) { if len(topics) != len(wps) {
return nil, fmt.Errorf("bad wait period list: got %d values, want %d", len(topics), len(wps)) return nil, fmt.Errorf("bad wait period list: got %d values, want %d", len(topics), len(wps))
} }
if rlpHash(topics) != p.data.(*pong).TopicHash { if rlpHash(topics) != p.data.(*pong).TopicHash {
return nil, fmt.Errorf("bad topic hash") return nil, errBadTopicHash
} }
t := &ticket{ t := &ticket{
issueTime: localTime, issueTime: localTime,

View file

@ -17,6 +17,7 @@
package nat package nat
import ( import (
"errors"
"fmt" "fmt"
"net" "net"
"strings" "strings"
@ -44,9 +45,11 @@ func (n *pmp) ExternalIP() (net.IP, error) {
return response.ExternalIPAddress[:], nil return response.ExternalIPAddress[:], nil
} }
var errPositiveLifetime = errors.New("lifetime must not be <= 0")
func (n *pmp) AddMapping(protocol string, extport, intport int, name string, lifetime time.Duration) error { func (n *pmp) AddMapping(protocol string, extport, intport int, name string, lifetime time.Duration) error {
if lifetime <= 0 { if lifetime <= 0 {
return fmt.Errorf("lifetime must not be <= 0") return errPositiveLifetime
} }
// Note order of port arguments is switched between our // Note order of port arguments is switched between our
// AddMapping and the client's AddPortMapping. // AddMapping and the client's AddPortMapping.

View file

@ -17,6 +17,7 @@
package p2p package p2p
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"net" "net"
@ -333,6 +334,10 @@ type protoRW struct {
w MsgWriter w MsgWriter
} }
var (
errShuttingDown = errors.New("shutting down")
)
func (rw *protoRW) WriteMsg(msg Msg) (err error) { func (rw *protoRW) WriteMsg(msg Msg) (err error) {
if msg.Code >= rw.Length { if msg.Code >= rw.Length {
return newPeerError(errInvalidMsgCode, "not handled") return newPeerError(errInvalidMsgCode, "not handled")
@ -347,7 +352,7 @@ func (rw *protoRW) WriteMsg(msg Msg) (err error) {
// as well but we don't want to rely on that. // as well but we don't want to rely on that.
rw.werr <- err rw.werr <- err
case <-rw.closed: case <-rw.closed:
err = fmt.Errorf("shutting down") err = errShuttingDown
} }
return err return err
} }

View file

@ -130,13 +130,18 @@ func (t *rlpx) doProtoHandshake(our *protoHandshake) (their *protoHandshake, err
return their, nil return their, nil
} }
var (
errMessageTooBig = errors.New("message too big")
errInvalidPublicKey = errors.New("invalid public key")
)
func readProtocolHandshake(rw MsgReader, our *protoHandshake) (*protoHandshake, error) { func readProtocolHandshake(rw MsgReader, our *protoHandshake) (*protoHandshake, error) {
msg, err := rw.ReadMsg() msg, err := rw.ReadMsg()
if err != nil { if err != nil {
return nil, err return nil, err
} }
if msg.Size > baseProtocolMaxMsgSize { if msg.Size > baseProtocolMaxMsgSize {
return nil, fmt.Errorf("message too big") return nil, errMessageTooBig
} }
if msg.Code == discMsg { if msg.Code == discMsg {
// Disconnect before protocol handshake is valid according to the // Disconnect before protocol handshake is valid according to the
@ -515,7 +520,7 @@ func importPublicKey(pubKey []byte) (*ecies.PublicKey, error) {
// TODO: fewer pointless conversions // TODO: fewer pointless conversions
pub := crypto.ToECDSAPub(pubKey65) pub := crypto.ToECDSAPub(pubKey65)
if pub.X == nil { if pub.X == nil {
return nil, fmt.Errorf("invalid public key") return nil, errInvalidPublicKey
} }
return ecies.ImportECDSAPublic(pub), nil return ecies.ImportECDSAPublic(pub), nil
} }

View file

@ -20,7 +20,6 @@ package p2p
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
"errors" "errors"
"fmt"
"net" "net"
"sync" "sync"
"time" "time"
@ -339,20 +338,25 @@ func (srv *Server) Stop() {
srv.loopWG.Wait() srv.loopWG.Wait()
} }
var (
errNilServerPrivateKey = errors.New("Server.PrivateKey must be set to a non-nil key")
errServerAlreadyRunning = errors.New("server already running")
)
// Start starts running the server. // Start starts running the server.
// Servers can not be re-used after stopping. // Servers can not be re-used after stopping.
func (srv *Server) Start() (err error) { func (srv *Server) Start() (err error) {
srv.lock.Lock() srv.lock.Lock()
defer srv.lock.Unlock() defer srv.lock.Unlock()
if srv.running { if srv.running {
return errors.New("server already running") return errServerAlreadyRunning
} }
srv.running = true srv.running = true
log.Info("Starting P2P networking") log.Info("Starting P2P networking")
// static fields // static fields
if srv.PrivateKey == nil { if srv.PrivateKey == nil {
return fmt.Errorf("Server.PrivateKey must be set to a non-nil key") return errNilServerPrivateKey
} }
if srv.newTransport == nil { if srv.newTransport == nil {
srv.newTransport = newRLPX srv.newTransport = newRLPX

View file

@ -17,6 +17,7 @@
package rlp package rlp
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"math/big" "math/big"
@ -428,9 +429,13 @@ func writeBigIntNoPtr(val reflect.Value, w *encbuf) error {
return writeBigInt(&i, w) return writeBigInt(&i, w)
} }
var (
errRLPEncodeNegativeBigInt = errors.New("rlp: cannot encode negative *big.Int")
)
func writeBigInt(i *big.Int, w *encbuf) error { func writeBigInt(i *big.Int, w *encbuf) error {
if cmp := i.Cmp(big0); cmp == -1 { if cmp := i.Cmp(big0); cmp == -1 {
return fmt.Errorf("rlp: cannot encode negative *big.Int") return errRLPEncodeNegativeBigInt
} else if cmp == 0 { } else if cmp == 0 {
w.str = append(w.str, 0x80) w.str = append(w.str, 0x80)
} else { } else {

View file

@ -19,6 +19,7 @@ package rpc
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io" "io"
"reflect" "reflect"
@ -134,11 +135,16 @@ func (c *jsonCodec) ReadRequestHeaders() ([]rpcRequest, bool, Error) {
return parseRequest(incomingMsg) return parseRequest(incomingMsg)
} }
var (
errMissingRequestID = errors.New("missing request id")
errInvalidRequestID = errors.New("invalid request id")
)
// checkReqId returns an error when the given reqId isn't valid for RPC method calls. // checkReqId returns an error when the given reqId isn't valid for RPC method calls.
// valid id's are strings, numbers or null // valid id's are strings, numbers or null
func checkReqId(reqId json.RawMessage) error { func checkReqId(reqId json.RawMessage) error {
if len(reqId) == 0 { if len(reqId) == 0 {
return fmt.Errorf("missing request id") return errMissingRequestID
} }
if _, err := strconv.ParseFloat(string(reqId), 64); err == nil { if _, err := strconv.ParseFloat(string(reqId), 64); err == nil {
return nil return nil
@ -147,7 +153,7 @@ func checkReqId(reqId json.RawMessage) error {
if err := json.Unmarshal(reqId, &str); err == nil { if err := json.Unmarshal(reqId, &str); err == nil {
return nil return nil
} }
return fmt.Errorf("invalid request id") return errInvalidRequestID
} }
// parseRequest will parse a single request from the given RawMessage. It will return // parseRequest will parse a single request from the given RawMessage. It will return

View file

@ -17,7 +17,7 @@
package rpc package rpc
import ( import (
"fmt" "errors"
"math" "math"
"reflect" "reflect"
"strings" "strings"
@ -124,6 +124,10 @@ const (
EarliestBlockNumber = BlockNumber(0) EarliestBlockNumber = BlockNumber(0)
) )
var (
errBlockNumberTooHigh = errors.New("Blocknumber too high")
)
// UnmarshalJSON parses the given JSON fragment into a BlockNumber. It supports: // UnmarshalJSON parses the given JSON fragment into a BlockNumber. It supports:
// - "latest", "earliest" or "pending" as string arguments // - "latest", "earliest" or "pending" as string arguments
// - the block number // - the block number
@ -153,7 +157,7 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error {
return err return err
} }
if blckNum > math.MaxInt64 { if blckNum > math.MaxInt64 {
return fmt.Errorf("Blocknumber too high") return errBlockNumberTooHigh
} }
*bn = BlockNumber(blckNum) *bn = BlockNumber(blckNum)

View file

@ -18,6 +18,7 @@ package api
import ( import (
"bufio" "bufio"
"errors"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
@ -41,6 +42,12 @@ func NewFileSystem(api *Api) *FileSystem {
return &FileSystem{api} return &FileSystem{api}
} }
var (
errPathTooShort = errors.New("Path is too short")
errAborted = errors.New("aborted")
errManifestNotFound = errors.New("Manifest not Found")
)
// Upload replicates a local directory as a manifest file and uploads it // Upload replicates a local directory as a manifest file and uploads it
// using dpa store // using dpa store
// TODO: localpath should point to a manifest // TODO: localpath should point to a manifest
@ -69,7 +76,7 @@ func (self *FileSystem) Upload(lpath, index string) (string, error) {
err = filepath.Walk(localpath, func(path string, info os.FileInfo, err error) error { err = filepath.Walk(localpath, func(path string, info os.FileInfo, err error) error {
if (err == nil) && !info.IsDir() { if (err == nil) && !info.IsDir() {
if len(path) <= start { if len(path) <= start {
return fmt.Errorf("Path is too short") return errPathTooShort
} }
if path[:start] != localpath { if path[:start] != localpath {
return fmt.Errorf("Path prefix of '%s' does not match localpath '%s'", path, localpath) return fmt.Errorf("Path prefix of '%s' does not match localpath '%s'", path, localpath)
@ -86,7 +93,7 @@ func (self *FileSystem) Upload(lpath, index string) (string, error) {
dir := filepath.Dir(localpath) dir := filepath.Dir(localpath)
start = len(dir) start = len(dir)
if len(localpath) <= start { if len(localpath) <= start {
return "", fmt.Errorf("Path is too short") return "", errPathTooShort
} }
if localpath[:start] != dir { if localpath[:start] != dir {
return "", fmt.Errorf("Path prefix of '%s' does not match dir '%s'", localpath, dir) return "", fmt.Errorf("Path prefix of '%s' does not match dir '%s'", localpath, dir)
@ -240,7 +247,7 @@ func (self *FileSystem) Download(bzzpath, localpath string) error {
case done <- true: case done <- true:
wg.Add(1) wg.Add(1)
case <-quitC: case <-quitC:
return fmt.Errorf("aborted") return errAborted
} }
go func(i int, entry *downloadListEntry) { go func(i int, entry *downloadListEntry) {
defer wg.Done() defer wg.Done()
@ -263,7 +270,7 @@ func (self *FileSystem) Download(bzzpath, localpath string) error {
case err = <-errC: case err = <-errC:
return err return err
case <-quitC: case <-quitC:
return fmt.Errorf("aborted") return errAborted
} }
} }

View file

@ -193,7 +193,7 @@ func readManifest(manifestReader storage.LazySectionReader, hash storage.Key, dp
size, err := manifestReader.Size(quitC) size, err := manifestReader.Size(quitC)
if err != nil { // size == 0 if err != nil { // size == 0
// can't determine size means we don't have the root chunk // can't determine size means we don't have the root chunk
err = fmt.Errorf("Manifest not Found") err = errManifestNotFound
return return
} }
manifestData := make([]byte, size) manifestData := make([]byte, size)
@ -379,7 +379,7 @@ func (self *manifestTrie) listWithPrefixInt(prefix, rp string, quitC chan bool,
for i := start; i <= stop; i++ { for i := start; i <= stop; i++ {
select { select {
case <-quitC: case <-quitC:
return fmt.Errorf("aborted") return errAborted
default: default:
} }
entry := self.entries[i] entry := self.entries[i]

View file

@ -20,13 +20,17 @@ package fuse
import ( import (
"context" "context"
"fmt" "errors"
"os/exec" "os/exec"
"runtime" "runtime"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
) )
var (
errUnmountUnimplemented = errors.New("unmount: unimplemented")
)
func externalUnmount(mountPoint string) error { func externalUnmount(mountPoint string) error {
ctx, cancel := context.WithTimeout(context.Background(), unmountTimeout) ctx, cancel := context.WithTimeout(context.Background(), unmountTimeout)
defer cancel() defer cancel()
@ -42,7 +46,7 @@ func externalUnmount(mountPoint string) error {
case "linux": case "linux":
return exec.CommandContext(ctx, "fusermount", "-u", mountPoint).Run() return exec.CommandContext(ctx, "fusermount", "-u", mountPoint).Run()
default: default:
return fmt.Errorf("unmount: unimplemented") return errUnmountUnimplemented
} }
} }

View file

@ -17,6 +17,7 @@
package network package network
import ( import (
"errors"
"fmt" "fmt"
"math/rand" "math/rand"
"path/filepath" "path/filepath"
@ -317,12 +318,16 @@ func (self *peer) LastActive() time.Time {
return self.lastActive return self.lastActive
} }
var (
errInvalidType = errors.New("invalid type")
)
// reads the serialised form of sync state persisted as the 'Meta' attribute // reads the serialised form of sync state persisted as the 'Meta' attribute
// and sets the decoded syncState on the online node // and sets the decoded syncState on the online node
func loadSync(record *kademlia.NodeRecord, node kademlia.Node) error { func loadSync(record *kademlia.NodeRecord, node kademlia.Node) error {
p, ok := node.(*peer) p, ok := node.(*peer)
if !ok { if !ok {
return fmt.Errorf("invalid type") return errInvalidType
} }
if record.Meta == nil { if record.Meta == nil {
log.Debug(fmt.Sprintf("no sync state for node record %v setting default", record)) log.Debug(fmt.Sprintf("no sync state for node record %v setting default", record))

View file

@ -17,6 +17,7 @@
package kademlia package kademlia
import ( import (
"errors"
"fmt" "fmt"
"sort" "sort"
"strings" "strings"
@ -113,6 +114,10 @@ func (self *Kademlia) DBCount() int {
return self.db.count() return self.db.count()
} }
var (
errBucketFull = errors.New("bucket full")
)
// On is the entry point called when a new nodes is added // On is the entry point called when a new nodes is added
// unsafe in that node is not checked to be already active node (to be called once) // unsafe in that node is not checked to be already active node (to be called once)
func (self *Kademlia) On(node Node, cb func(*NodeRecord, Node) error) (err error) { func (self *Kademlia) On(node Node, cb func(*NodeRecord, Node) error) (err error) {
@ -159,7 +164,7 @@ func (self *Kademlia) On(node Node, cb func(*NodeRecord, Node) error) (err error
} }
if replaced == nil { if replaced == nil {
log.Debug(fmt.Sprintf("all peers wanted, PO%03d bucket full", index)) log.Debug(fmt.Sprintf("all peers wanted, PO%03d bucket full", index))
return fmt.Errorf("bucket full") return errBucketFull
} }
log.Debug(fmt.Sprintf("node %v replaced by %v (idle for %v > %v)", replaced, node, idle, self.MaxIdleInterval)) log.Debug(fmt.Sprintf("node %v replaced by %v (idle for %v > %v)", replaced, node, idle, self.MaxIdleInterval))
replaced.Drop() replaced.Drop()

View file

@ -183,6 +183,11 @@ func (self *bzz) Drop() {
self.peer.Disconnect(p2p.DiscSubprotocolError) self.peer.Disconnect(p2p.DiscSubprotocolError)
} }
var (
errProtocolHandlerNilReqKey = errors.New("protocol handler: req.Key == nil || req.Timeout == nil")
errNetworkWriteBlocked = errors.New("network write blocked")
)
// one cycle of the main forever loop that handles and dispatches incoming messages // one cycle of the main forever loop that handles and dispatches incoming messages
func (self *bzz) handle() error { func (self *bzz) handle() error {
msg, err := self.rw.ReadMsg() msg, err := self.rw.ReadMsg()
@ -230,7 +235,7 @@ func (self *bzz) handle() error {
if req.isLookup() { if req.isLookup() {
log.Trace(fmt.Sprintf("self lookup for %v: responding with peers only...", req.from)) log.Trace(fmt.Sprintf("self lookup for %v: responding with peers only...", req.from))
} else if req.Key == nil { } else if req.Key == nil {
return fmt.Errorf("protocol handler: req.Key == nil || req.Timeout == nil") return errProtocolHandlerNilReqKey
} else { } else {
// swap accounting is done within netStore // swap accounting is done within netStore
self.storage.HandleRetrieveRequestMsg(&req, &peer{bzz: self}) self.storage.HandleRetrieveRequestMsg(&req, &peer{bzz: self})
@ -499,7 +504,7 @@ func (self *bzz) peers(req *peersMsgData) error {
func (self *bzz) send(msg uint64, data interface{}) error { func (self *bzz) send(msg uint64, data interface{}) error {
if self.hive.blockWrite { if self.hive.blockWrite {
return fmt.Errorf("network write blocked") return errNetworkWriteBlocked
} }
log.Trace(fmt.Sprintf("-> %v: %v (%T) to %v", msg, data, data, self)) log.Trace(fmt.Sprintf("-> %v: %v (%T) to %v", msg, data, data, self))
err := p2p.Send(self.rw, msg, data) err := p2p.Send(self.rw, msg, data)

View file

@ -19,6 +19,7 @@ package network
import ( import (
"encoding/binary" "encoding/binary"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"path/filepath" "path/filepath"
@ -230,13 +231,17 @@ func encodeSync(state *syncState) (*json.RawMessage, error) {
return &meta, nil return &meta, nil
} }
var (
errDecodeNilSyncState = errors.New("unable to deserialise sync state from <nil>")
)
func decodeSync(meta *json.RawMessage) (*syncState, error) { func decodeSync(meta *json.RawMessage) (*syncState, error) {
if meta == nil { if meta == nil {
return nil, fmt.Errorf("unable to deserialise sync state from <nil>") return nil, errDecodeNilSyncState
} }
data := []byte(*(meta)) data := []byte(*(meta))
if len(data) == 0 { if len(data) == 0 {
return nil, fmt.Errorf("unable to deserialise sync state from <nil>") return nil, errDecodeNilSyncState
} }
state := &syncState{DbSyncState: &storage.DbSyncState{}} state := &syncState{DbSyncState: &storage.DbSyncState{}}
err := json.Unmarshal(data, state) err := json.Unmarshal(data, state)

View file

@ -27,6 +27,7 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"errors"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@ -550,10 +551,14 @@ type dbSyncIterator struct {
DbSyncState DbSyncState
} }
var (
errNoEntriesFound = errors.New("no entries found")
)
// initialises a sync iterator from a syncToken (passed in with the handshake) // initialises a sync iterator from a syncToken (passed in with the handshake)
func (self *DbStore) NewSyncIterator(state DbSyncState) (si *dbSyncIterator, err error) { func (self *DbStore) NewSyncIterator(state DbSyncState) (si *dbSyncIterator, err error) {
if state.First > state.Last { if state.First > state.Last {
return nil, fmt.Errorf("no entries found") return nil, errNoEntriesFound
} }
si = &dbSyncIterator{ si = &dbSyncIterator{
it: self.db.NewIterator(), it: self.db.NewIterator(),

View file

@ -20,6 +20,7 @@ import (
"bytes" "bytes"
"context" "context"
"crypto/ecdsa" "crypto/ecdsa"
"errors"
"fmt" "fmt"
"net" "net"
@ -74,14 +75,19 @@ func (self *Swarm) API() *SwarmAPI {
} }
} }
var (
errEmptyPublicKey = errors.New("empty public key")
errEmptyBzzKey = errors.New("empty bzz key")
)
// creates a new swarm service instance // creates a new swarm service instance
// implements node.Service // implements node.Service
func NewSwarm(ctx *node.ServiceContext, backend chequebook.Backend, ensClient *ethclient.Client, config *api.Config, swapEnabled, syncEnabled bool, cors string) (self *Swarm, err error) { func NewSwarm(ctx *node.ServiceContext, backend chequebook.Backend, ensClient *ethclient.Client, config *api.Config, swapEnabled, syncEnabled bool, cors string) (self *Swarm, err error) {
if bytes.Equal(common.FromHex(config.PublicKey), storage.ZeroKey) { if bytes.Equal(common.FromHex(config.PublicKey), storage.ZeroKey) {
return nil, fmt.Errorf("empty public key") return nil, errEmptyPublicKey
} }
if bytes.Equal(common.FromHex(config.BzzKey), storage.ZeroKey) { if bytes.Equal(common.FromHex(config.BzzKey), storage.ZeroKey) {
return nil, fmt.Errorf("empty bzz key") return nil, errEmptyBzzKey
} }
self = &Swarm{ self = &Swarm{

View file

@ -18,6 +18,7 @@ package whisperv2
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"sync" "sync"
"time" "time"
@ -243,6 +244,12 @@ func (args *PostArgs) UnmarshalJSON(data []byte) (err error) {
return nil return nil
} }
var (
errToNotAString = errors.New("to is not a string")
errFromNotAString = errors.New("from is not a string")
errTopicsNotArray = errors.New("topics is not an array")
)
// UnmarshalJSON implements the json.Unmarshaler interface, invoked to convert a // UnmarshalJSON implements the json.Unmarshaler interface, invoked to convert a
// JSON message blob into a WhisperFilterArgs structure. // JSON message blob into a WhisperFilterArgs structure.
func (args *NewFilterArgs) UnmarshalJSON(b []byte) (err error) { func (args *NewFilterArgs) UnmarshalJSON(b []byte) (err error) {
@ -262,7 +269,7 @@ func (args *NewFilterArgs) UnmarshalJSON(b []byte) (err error) {
} else { } else {
argstr, ok := obj.To.(string) argstr, ok := obj.To.(string)
if !ok { if !ok {
return fmt.Errorf("to is not a string") return errToNotAString
} }
args.To = argstr args.To = argstr
} }
@ -271,7 +278,7 @@ func (args *NewFilterArgs) UnmarshalJSON(b []byte) (err error) {
} else { } else {
argstr, ok := obj.From.(string) argstr, ok := obj.From.(string)
if !ok { if !ok {
return fmt.Errorf("from is not a string") return errFromNotAString
} }
args.From = argstr args.From = argstr
} }
@ -280,7 +287,7 @@ func (args *NewFilterArgs) UnmarshalJSON(b []byte) (err error) {
// Make sure we have an actual topic array // Make sure we have an actual topic array
list, ok := obj.Topics.([]interface{}) list, ok := obj.Topics.([]interface{})
if !ok { if !ok {
return fmt.Errorf("topics is not an array") return errTopicsNotArray
} }
// Iterate over each topic and handle nil, string or array // Iterate over each topic and handle nil, string or array
topics := make([][]string, len(list)) topics := make([][]string, len(list))

View file

@ -22,6 +22,7 @@ package whisperv2
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
"encoding/binary" "encoding/binary"
"errors"
"fmt" "fmt"
"math/big" "math/big"
"time" "time"
@ -84,6 +85,10 @@ func (self *Envelope) rlpWithoutNonce() []byte {
return enc return enc
} }
var (
errUnableToOpenEnvelope = errors.New("unable to open envelope. First bit set but len(data) < len(signature)")
)
// Open extracts the message contained within a potentially encrypted envelope. // Open extracts the message contained within a potentially encrypted envelope.
func (self *Envelope) Open(key *ecdsa.PrivateKey) (msg *Message, err error) { func (self *Envelope) Open(key *ecdsa.PrivateKey) (msg *Message, err error) {
// Split open the payload into a message construct // Split open the payload into a message construct
@ -99,7 +104,7 @@ func (self *Envelope) Open(key *ecdsa.PrivateKey) (msg *Message, err error) {
if message.Flags&signatureFlag == signatureFlag { if message.Flags&signatureFlag == signatureFlag {
if len(data) < signatureLength { if len(data) < signatureLength {
return nil, fmt.Errorf("unable to open envelope. First bit set but len(data) < len(signature)") return nil, errUnableToOpenEnvelope
} }
message.Signature, data = data[:signatureLength], data[signatureLength:] message.Signature, data = data[:signatureLength], data[signatureLength:]
} }

View file

@ -22,6 +22,7 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"log" "log"
"os" "os"
@ -70,6 +71,8 @@ func main() {
} }
} }
var errMsgRecvTimedout = errors.New("failed to receive message in time")
// SendSelf wraps a payload into a Whisper envelope and forwards it to itself. // SendSelf wraps a payload into a Whisper envelope and forwards it to itself.
func selfSend(shh *whisper.Whisper, payload []byte) error { func selfSend(shh *whisper.Whisper, payload []byte) error {
ok := make(chan struct{}) ok := make(chan struct{})
@ -100,7 +103,7 @@ func selfSend(shh *whisper.Whisper, payload []byte) error {
select { select {
case <-ok: case <-ok:
case <-time.After(time.Second): case <-time.After(time.Second):
return fmt.Errorf("failed to receive message in time") return errMsgRecvTimedout
} }
return nil return nil
} }

View file

@ -104,7 +104,7 @@ func (api *PublicWhisperAPI) Info(ctx context.Context) Info {
stats := api.w.Stats() stats := api.w.Stats()
return Info{ return Info{
Memory: stats.memoryUsed, Memory: stats.memoryUsed,
Messages: len(api.w.messageQueue) + len(api.w.p2pMsgQueue), Messages: len(api.w.messageQueue) + len(api.w.p2pMsgQueue),
MinPow: api.w.MinPow(), MinPow: api.w.MinPow(),
MaxMessageSize: api.w.MaxMessageSize(), MaxMessageSize: api.w.MaxMessageSize(),
} }
@ -489,6 +489,10 @@ func toMessage(messages []*ReceivedMessage) []*Message {
return msgs return msgs
} }
var (
errFilterNotFound = errors.New("filter not found")
)
// GetFilterMessages returns the messages that match the filter criteria and // GetFilterMessages returns the messages that match the filter criteria and
// are received between the last poll and now. // are received between the last poll and now.
func (api *PublicWhisperAPI) GetFilterMessages(id string) ([]*Message, error) { func (api *PublicWhisperAPI) GetFilterMessages(id string) ([]*Message, error) {
@ -496,7 +500,7 @@ func (api *PublicWhisperAPI) GetFilterMessages(id string) ([]*Message, error) {
f := api.w.GetFilter(id) f := api.w.GetFilter(id)
if f == nil { if f == nil {
api.mu.Unlock() api.mu.Unlock()
return nil, fmt.Errorf("filter not found") return nil, errFilterNotFound
} }
api.lastUsed[id] = time.Now() api.lastUsed[id] = time.Now()
api.mu.Unlock() api.mu.Unlock()

View file

@ -65,7 +65,7 @@ func (fs *Filters) Install(watcher *Filter) (string, error) {
defer fs.mutex.Unlock() defer fs.mutex.Unlock()
if fs.watchers[id] != nil { if fs.watchers[id] != nil {
return "", fmt.Errorf("failed to generate unique ID") return "", errFailedToGenerateUniqueID
} }
fs.watchers[id] = watcher fs.watchers[id] = watcher

View file

@ -236,6 +236,22 @@ func (w *Whisper) SendP2PDirect(peer *Peer, envelope *Envelope) error {
return p2p.Send(peer.ws, p2pCode, envelope) return p2p.Send(peer.ws, p2pCode, envelope)
} }
var (
errInvalidID = errors.New("invalid id")
errVeryOldMessage = errors.New("very old message")
errFailedToGenerateUniqueID = errors.New("failed to generate unique ID")
errFailedToGenerateValidKey = errors.New("failed to generate valid key")
errFailedToAddEnvelope = errors.New("failed to add envelope")
errNonExistentKeyID = errors.New("non-existent key ID")
errUnsubscribeInvalidID = errors.New("Unsubscribe: Invalid ID")
errInvalidP2PRequest = errors.New("invalid p2p request")
errInvalidDirectMessage = errors.New("invalid direct message")
errGenRandomIDRandomData = errors.New("error in generateRandomID: crypto/rand failed to generate random data")
errGenSymKeyRandomData = errors.New("error in GenerateSymKey: crypto/rand failed to generate random data")
errCriticalFailedToGenerateUniqueID = errors.New("critical error: failed to generate unique ID")
)
// NewKeyPair generates a new cryptographic identity for the client, and injects // NewKeyPair generates a new cryptographic identity for the client, and injects
// it into the known identities for message decryption. Returns ID of the new key pair. // it into the known identities for message decryption. Returns ID of the new key pair.
func (w *Whisper) NewKeyPair() (string, error) { func (w *Whisper) NewKeyPair() (string, error) {
@ -247,7 +263,7 @@ func (w *Whisper) NewKeyPair() (string, error) {
return "", err return "", err
} }
if !validatePrivateKey(key) { if !validatePrivateKey(key) {
return "", fmt.Errorf("failed to generate valid key") return "", errFailedToGenerateValidKey
} }
id, err := GenerateRandomID() id, err := GenerateRandomID()
@ -259,7 +275,7 @@ func (w *Whisper) NewKeyPair() (string, error) {
defer w.keyMu.Unlock() defer w.keyMu.Unlock()
if w.privateKeys[id] != nil { if w.privateKeys[id] != nil {
return "", fmt.Errorf("failed to generate unique ID") return "", errFailedToGenerateUniqueID
} }
w.privateKeys[id] = key w.privateKeys[id] = key
return id, nil return id, nil
@ -305,7 +321,7 @@ func (w *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) {
defer w.keyMu.RUnlock() defer w.keyMu.RUnlock()
key := w.privateKeys[id] key := w.privateKeys[id]
if key == nil { if key == nil {
return nil, fmt.Errorf("invalid id") return nil, errInvalidID
} }
return key, nil return key, nil
} }
@ -318,7 +334,7 @@ func (w *Whisper) GenerateSymKey() (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} else if !validateSymmetricKey(key) { } else if !validateSymmetricKey(key) {
return "", fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data") return "", errGenSymKeyRandomData
} }
id, err := GenerateRandomID() id, err := GenerateRandomID()
@ -330,7 +346,7 @@ func (w *Whisper) GenerateSymKey() (string, error) {
defer w.keyMu.Unlock() defer w.keyMu.Unlock()
if w.symKeys[id] != nil { if w.symKeys[id] != nil {
return "", fmt.Errorf("failed to generate unique ID") return "", errFailedToGenerateUniqueID
} }
w.symKeys[id] = key w.symKeys[id] = key
return id, nil return id, nil
@ -351,7 +367,7 @@ func (w *Whisper) AddSymKeyDirect(key []byte) (string, error) {
defer w.keyMu.Unlock() defer w.keyMu.Unlock()
if w.symKeys[id] != nil { if w.symKeys[id] != nil {
return "", fmt.Errorf("failed to generate unique ID") return "", errFailedToGenerateUniqueID
} }
w.symKeys[id] = key w.symKeys[id] = key
return id, nil return id, nil
@ -364,7 +380,7 @@ func (w *Whisper) AddSymKeyFromPassword(password string) (string, error) {
return "", fmt.Errorf("failed to generate ID: %s", err) return "", fmt.Errorf("failed to generate ID: %s", err)
} }
if w.HasSymKey(id) { if w.HasSymKey(id) {
return "", fmt.Errorf("failed to generate unique ID") return "", errFailedToGenerateUniqueID
} }
derived, err := deriveKeyMaterial([]byte(password), EnvelopeVersion) derived, err := deriveKeyMaterial([]byte(password), EnvelopeVersion)
@ -377,7 +393,7 @@ func (w *Whisper) AddSymKeyFromPassword(password string) (string, error) {
// double check is necessary, because deriveKeyMaterial() is very slow // double check is necessary, because deriveKeyMaterial() is very slow
if w.symKeys[id] != nil { if w.symKeys[id] != nil {
return "", fmt.Errorf("critical error: failed to generate unique ID") return "", errCriticalFailedToGenerateUniqueID
} }
w.symKeys[id] = derived w.symKeys[id] = derived
return id, nil return id, nil
@ -409,7 +425,7 @@ func (w *Whisper) GetSymKey(id string) ([]byte, error) {
if w.symKeys[id] != nil { if w.symKeys[id] != nil {
return w.symKeys[id], nil return w.symKeys[id], nil
} }
return nil, fmt.Errorf("non-existent key ID") return nil, errNonExistentKeyID
} }
// Subscribe installs a new message handler used for filtering, decrypting // Subscribe installs a new message handler used for filtering, decrypting
@ -427,7 +443,7 @@ func (w *Whisper) GetFilter(id string) *Filter {
func (w *Whisper) Unsubscribe(id string) error { func (w *Whisper) Unsubscribe(id string) error {
ok := w.filters.Uninstall(id) ok := w.filters.Uninstall(id)
if !ok { if !ok {
return fmt.Errorf("Unsubscribe: Invalid ID") return errUnsubscribeInvalidID
} }
return nil return nil
} }
@ -440,7 +456,7 @@ func (w *Whisper) Send(envelope *Envelope) error {
return err return err
} }
if !ok { if !ok {
return fmt.Errorf("failed to add envelope") return errFailedToAddEnvelope
} }
return err return err
} }
@ -535,7 +551,7 @@ func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
var envelope Envelope var envelope Envelope
if err := packet.Decode(&envelope); err != nil { if err := packet.Decode(&envelope); err != nil {
log.Warn("failed to decode direct message, peer will be disconnected", "peer", p.peer.ID(), "err", err) log.Warn("failed to decode direct message, peer will be disconnected", "peer", p.peer.ID(), "err", err)
return errors.New("invalid direct message") return errInvalidDirectMessage
} }
wh.postEvent(&envelope, true) wh.postEvent(&envelope, true)
} }
@ -545,7 +561,7 @@ func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
var request Envelope var request Envelope
if err := packet.Decode(&request); err != nil { if err := packet.Decode(&request); err != nil {
log.Warn("failed to decode p2p request message, peer will be disconnected", "peer", p.peer.ID(), "err", err) log.Warn("failed to decode p2p request message, peer will be disconnected", "peer", p.peer.ID(), "err", err)
return errors.New("invalid p2p request") return errInvalidP2PRequest
} }
wh.mailServer.DeliverMail(p, &request) wh.mailServer.DeliverMail(p, &request)
} }
@ -576,7 +592,7 @@ func (wh *Whisper) add(envelope *Envelope) (bool, error) {
if envelope.Expiry < now { if envelope.Expiry < now {
if envelope.Expiry+SynchAllowance*2 < now { if envelope.Expiry+SynchAllowance*2 < now {
return false, fmt.Errorf("very old message") return false, errVeryOldMessage
} else { } else {
log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex()) log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex())
return false, nil // drop envelope without error return false, nil // drop envelope without error
@ -851,7 +867,7 @@ func GenerateRandomID() (id string, err error) {
return "", err return "", err
} }
if !validateSymmetricKey(buf) { if !validateSymmetricKey(buf) {
return "", fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data") return "", errGenRandomIDRandomData
} }
id = common.Bytes2Hex(buf) id = common.Bytes2Hex(buf)
return id, err return id, err