mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-16 17:03:46 +00:00
Merge 36edd2f27b into 673007d7ae
This commit is contained in:
commit
5ac1b8436b
46 changed files with 322 additions and 113 deletions
|
|
@ -18,6 +18,7 @@ package abi
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
|
|
@ -85,12 +86,16 @@ var (
|
|||
r_byte = reflect.TypeOf(byte(0))
|
||||
)
|
||||
|
||||
var (
|
||||
errEmptyABIOutput = errors.New("abi: unmarshalling empty output")
|
||||
)
|
||||
|
||||
// Unpack output in v according to the abi specification
|
||||
func (abi ABI) Unpack(v interface{}, name string, output []byte) error {
|
||||
var method = abi.Methods[name]
|
||||
|
||||
if len(output) == 0 {
|
||||
return fmt.Errorf("abi: unmarshalling empty output")
|
||||
return errEmptyABIOutput
|
||||
}
|
||||
|
||||
// make sure the passed value is a pointer
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ package bind
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"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
|
||||
// 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) {
|
||||
if tx.To() != nil {
|
||||
return common.Address{}, fmt.Errorf("tx is not contract creation")
|
||||
return common.Address{}, errTxNotContractCreation
|
||||
}
|
||||
receipt, err := WaitMined(ctx, b, tx)
|
||||
if err != nil {
|
||||
return common.Address{}, err
|
||||
}
|
||||
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.
|
||||
// This matters on pre-Homestead chains: OOG in the constructor
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package abi
|
|||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"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) {
|
||||
if len(word) != 32 {
|
||||
return false, fmt.Errorf("abi: fatal error: incorrect word length")
|
||||
return false, errIncorrectWordLength
|
||||
}
|
||||
|
||||
for i, b := range word {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import (
|
|||
"crypto/ecdsa"
|
||||
crand "crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
|
@ -44,6 +43,8 @@ var (
|
|||
ErrLocked = accounts.NewAuthNeededError("password or unlock")
|
||||
ErrNoMatch = errors.New("no key for given address or file")
|
||||
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.
|
||||
|
|
@ -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) {
|
||||
key := newKeyFromECDSA(priv)
|
||||
if ks.cache.hasAddress(key.Address) {
|
||||
return accounts.Account{}, fmt.Errorf("account already exists")
|
||||
return accounts.Account{}, errAccountExists
|
||||
}
|
||||
return ks.importKey(key, passphrase)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package utils
|
|||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
|
@ -80,6 +81,8 @@ func StartNode(stack *node.Node) {
|
|||
}()
|
||||
}
|
||||
|
||||
var errInterrupted = errors.New("interrupted")
|
||||
|
||||
func ImportChain(chain *core.BlockChain, fn string) error {
|
||||
// Watch for Ctrl-C while the import is running.
|
||||
// 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++ {
|
||||
// Load a batch of RLP blocks.
|
||||
if checkInterrupt() {
|
||||
return fmt.Errorf("interrupted")
|
||||
return errInterrupted
|
||||
}
|
||||
i := 0
|
||||
for ; i < importBatchSize; i++ {
|
||||
|
|
@ -148,7 +151,7 @@ func ImportChain(chain *core.BlockChain, fn string) error {
|
|||
}
|
||||
// Import the batch.
|
||||
if checkInterrupt() {
|
||||
return fmt.Errorf("interrupted")
|
||||
return errInterrupted
|
||||
}
|
||||
if hasAllBlocks(chain, blocks[:i]) {
|
||||
log.Info("Skipping batch as all blocks present", "batch", batch, "first", blocks[0].Hash(), "last", blocks[i-1].Hash())
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import (
|
|||
"context"
|
||||
"crypto/ecdsa"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
|
|
@ -443,11 +444,16 @@ type Inbox struct {
|
|||
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
|
||||
// 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) {
|
||||
if signer == nil {
|
||||
return nil, fmt.Errorf("signer is null")
|
||||
return nil, errNilSigner
|
||||
}
|
||||
chbook, err := contract.NewChequebook(contractAddr, abigen)
|
||||
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) {
|
||||
log.Trace("Verifying chequebook cheque", "cheque", self, "sum", sum)
|
||||
if sum == nil {
|
||||
return nil, fmt.Errorf("invalid amount")
|
||||
return nil, errInvalidAmount
|
||||
}
|
||||
|
||||
if self.Beneficiary != beneficiary {
|
||||
|
|
|
|||
|
|
@ -1062,6 +1062,11 @@ func countTransactions(chain []*types.Block) (c int) {
|
|||
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
|
||||
// to be part of the new canonical chain and accumulates potential missing transactions and post an
|
||||
// event about them
|
||||
|
|
@ -1104,10 +1109,10 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
|
|||
}
|
||||
}
|
||||
if oldBlock == nil {
|
||||
return fmt.Errorf("Invalid old chain")
|
||||
return errInvalidOldChain
|
||||
}
|
||||
if newBlock == nil {
|
||||
return fmt.Errorf("Invalid new chain")
|
||||
return errInvalidNewChain
|
||||
}
|
||||
|
||||
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)
|
||||
if oldBlock == nil {
|
||||
return fmt.Errorf("Invalid old chain")
|
||||
return errInvalidOldChain
|
||||
}
|
||||
if newBlock == nil {
|
||||
return fmt.Errorf("Invalid new chain")
|
||||
return errInvalidNewChain
|
||||
}
|
||||
}
|
||||
// Ensure the user sees large reorgs
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package core
|
|||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"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
|
||||
// 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
|
||||
|
|
@ -322,7 +327,7 @@ func (c *ChainIndexer) processSection(section uint64, lastHead common.Hash) (com
|
|||
if header == nil {
|
||||
return common.Hash{}, fmt.Errorf("block #%d [%x…] not found", number, hash[:4])
|
||||
} else if header.ParentHash != lastHead {
|
||||
return common.Hash{}, fmt.Errorf("chain reorged during section processing")
|
||||
return common.Hash{}, errChainReorgedInProcessing
|
||||
}
|
||||
c.backend.Process(header)
|
||||
lastHead = header.Hash()
|
||||
|
|
|
|||
|
|
@ -39,7 +39,11 @@ import (
|
|||
//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
|
||||
|
||||
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
|
||||
// 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.
|
||||
height := GetBlockNumber(db, GetHeadHeaderHash(db))
|
||||
if height == missingNumber {
|
||||
return newcfg, stored, fmt.Errorf("missing block number for head header hash")
|
||||
return newcfg, stored, errMissingHeaderHashBlockNumber
|
||||
}
|
||||
compatErr := storedcfg.CheckCompatible(newcfg, height)
|
||||
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) {
|
||||
block, statedb := g.ToBlock()
|
||||
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 {
|
||||
return nil, fmt.Errorf("cannot write state: %v", err)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import (
|
|||
"crypto/elliptic"
|
||||
"crypto/hmac"
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
|
|
@ -42,12 +43,12 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
ErrImport = fmt.Errorf("ecies: failed to import key")
|
||||
ErrInvalidCurve = fmt.Errorf("ecies: invalid elliptic curve")
|
||||
ErrInvalidParams = fmt.Errorf("ecies: invalid ECIES parameters")
|
||||
ErrInvalidPublicKey = fmt.Errorf("ecies: invalid public key")
|
||||
ErrSharedKeyIsPointAtInfinity = fmt.Errorf("ecies: shared key is point at infinity")
|
||||
ErrSharedKeyTooBig = fmt.Errorf("ecies: shared key params are too big")
|
||||
ErrImport = errors.New("ecies: failed to import key")
|
||||
ErrInvalidCurve = errors.New("ecies: invalid elliptic curve")
|
||||
ErrInvalidParams = errors.New("ecies: invalid ECIES parameters")
|
||||
ErrInvalidPublicKey = errors.New("ecies: invalid public key")
|
||||
ErrSharedKeyIsPointAtInfinity = errors.New("ecies: shared key is point at infinity")
|
||||
ErrSharedKeyTooBig = errors.New("ecies: shared key params are too big")
|
||||
)
|
||||
|
||||
// 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 (
|
||||
ErrKeyDataTooLong = fmt.Errorf("ecies: can't supply requested key data")
|
||||
ErrSharedTooLong = fmt.Errorf("ecies: shared secret is too long")
|
||||
ErrInvalidMessage = fmt.Errorf("ecies: invalid message")
|
||||
ErrKeyDataTooLong = errors.New("ecies: can't supply requested key data")
|
||||
ErrSharedTooLong = errors.New("ecies: shared secret is too long")
|
||||
ErrInvalidMessage = errors.New("ecies: invalid message")
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ import (
|
|||
"crypto/elliptic"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"fmt"
|
||||
"errors"
|
||||
"hash"
|
||||
|
||||
ethcrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
|
|
@ -47,8 +47,8 @@ import (
|
|||
|
||||
var (
|
||||
DefaultCurve = ethcrypto.S256()
|
||||
ErrUnsupportedECDHAlgorithm = fmt.Errorf("ecies: unsupported ECDH algorithm")
|
||||
ErrUnsupportedECIESParameters = fmt.Errorf("ecies: unsupported ECIES parameters")
|
||||
ErrUnsupportedECDHAlgorithm = errors.New("ecies: unsupported ECDH algorithm")
|
||||
ErrUnsupportedECIESParameters = errors.New("ecies: unsupported ECIES parameters")
|
||||
)
|
||||
|
||||
type ECIESParams struct {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@ func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) {
|
|||
return (*ecdsa.PublicKey)(pub), err
|
||||
}
|
||||
|
||||
var (
|
||||
errPrivKeyCurveNotSecp256k1 = errors.New("private key curve is not secp256k1")
|
||||
)
|
||||
|
||||
// Sign calculates an ECDSA signature.
|
||||
//
|
||||
// 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))
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -292,6 +292,10 @@ func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) {
|
|||
s.blockchain.ResetWithGenesisBlock(gb)
|
||||
}
|
||||
|
||||
var (
|
||||
errEtherbaseAddressWanted = errors.New("etherbase address must be explicitly specified")
|
||||
)
|
||||
|
||||
func (s *Ethereum) Etherbase() (eb common.Address, err error) {
|
||||
s.lock.RLock()
|
||||
etherbase := s.etherbase
|
||||
|
|
@ -305,7 +309,7 @@ func (s *Ethereum) Etherbase() (eb common.Address, err error) {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -357,6 +357,11 @@ func (api *PublicFilterAPI) UninstallFilter(id rpc.ID) bool {
|
|||
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.
|
||||
// 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()
|
||||
|
||||
if !found || f.typ != LogsSubscription {
|
||||
return nil, fmt.Errorf("filter not found")
|
||||
return nil, errFilterNotFound
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
@ -519,11 +524,11 @@ func (args *FilterCriteria) UnmarshalJSON(data []byte) error {
|
|||
}
|
||||
args.Topics[i] = append(args.Topics[i], parsed)
|
||||
} else {
|
||||
return fmt.Errorf("invalid topic(s)")
|
||||
return errInvalidTopics
|
||||
}
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("invalid topic(s)")
|
||||
return errInvalidTopics
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ package filters
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
|
@ -69,6 +68,8 @@ const (
|
|||
|
||||
var (
|
||||
ErrInvalidSubscriptionID = errors.New("invalid id")
|
||||
|
||||
errInvalidFromToBlockCombination = errors.New("invalid from and to block combination: from > to")
|
||||
)
|
||||
|
||||
type subscription struct {
|
||||
|
|
@ -195,7 +196,7 @@ func (es *EventSystem) SubscribeLogs(crit FilterCriteria, logs chan []*types.Log
|
|||
if from >= 0 && to == rpc.LatestBlockNumber {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package ethclient
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"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.
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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.
|
||||
var uncles []*types.Header
|
||||
|
|
@ -153,6 +154,14 @@ func (ec *Client) HeaderByNumber(ctx context.Context, number *big.Int) (*types.H
|
|||
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.
|
||||
func (ec *Client) TransactionByHash(ctx context.Context, hash common.Hash) (tx *types.Transaction, isPending bool, err error) {
|
||||
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 {
|
||||
return nil, false, err
|
||||
} 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 }
|
||||
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 {
|
||||
return nil, ethereum.NotFound
|
||||
} else if _, r, _ := tx.RawSignatureValues(); r == nil {
|
||||
return nil, fmt.Errorf("server returned transaction without signature")
|
||||
return nil, errServerTxWithoutSignature
|
||||
}
|
||||
}
|
||||
return tx, err
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"archive/tar"
|
||||
"archive/zip"
|
||||
"compress/gzip"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
|
@ -73,6 +74,10 @@ func AddFile(a Archive, file string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
errUnknownArchiveExtension = errors.New("unknown archive extension")
|
||||
)
|
||||
|
||||
// WriteArchive creates an archive containing the given files.
|
||||
func WriteArchive(name string, files []string) (err error) {
|
||||
archfd, err := os.Create(name)
|
||||
|
|
@ -89,7 +94,7 @@ func WriteArchive(name string, files []string) (err error) {
|
|||
}()
|
||||
archive, basename := NewArchive(archfd)
|
||||
if archive == nil {
|
||||
return fmt.Errorf("unknown archive extension")
|
||||
return errUnknownArchiveExtension
|
||||
}
|
||||
fmt.Println(name)
|
||||
if err := archive.Directory(basename); err != nil {
|
||||
|
|
|
|||
|
|
@ -408,6 +408,15 @@ func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr c
|
|||
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.
|
||||
// Note, this function is compatible with eth_sign and personal_sign. As such it recovers
|
||||
// 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
|
||||
func (s *PrivateAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) {
|
||||
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 {
|
||||
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
|
||||
|
||||
|
|
@ -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.
|
||||
func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxArgs, gasPrice, gasLimit *hexutil.Big) (common.Hash, error) {
|
||||
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 {
|
||||
return common.Hash{}, err
|
||||
|
|
@ -1336,7 +1345,7 @@ func (api *PrivateDebugAPI) ChaindbProperty(property string) (string, error) {
|
|||
LDB() *leveldb.DB
|
||||
})
|
||||
if !ok {
|
||||
return "", fmt.Errorf("chaindbProperty does not work for memory databases")
|
||||
return "", errChainDBPropertyNotForMemoryDB
|
||||
}
|
||||
if property == "" {
|
||||
property = "leveldb.stats"
|
||||
|
|
@ -1351,7 +1360,7 @@ func (api *PrivateDebugAPI) ChaindbCompact() error {
|
|||
LDB() *leveldb.DB
|
||||
})
|
||||
if !ok {
|
||||
return fmt.Errorf("chaindbCompact does not work for memory databases")
|
||||
return errChainDBCompactNotForMemoryDB
|
||||
}
|
||||
for b := byte(0); b < 255; b++ {
|
||||
log.Info("Compacting chain database", "range", fmt.Sprintf("0x%0.2X-0x%0.2X", b, b+1))
|
||||
|
|
|
|||
|
|
@ -215,6 +215,11 @@ type JavascriptTracer struct {
|
|||
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.
|
||||
// code specifies a Javascript snippet, which must evaluate to an expression
|
||||
// returning an object with 'step' and 'result' functions.
|
||||
|
|
@ -237,7 +242,7 @@ func NewJavascriptTracer(code string) (*JavascriptTracer, error) {
|
|||
return nil, err
|
||||
}
|
||||
if !step.IsFunction() {
|
||||
return nil, fmt.Errorf("Trace object must expose a function step()")
|
||||
return nil, errTraceMustExposeFunctionStep
|
||||
}
|
||||
|
||||
result, err := jstracer.Get("result")
|
||||
|
|
@ -245,7 +250,7 @@ func NewJavascriptTracer(code string) (*JavascriptTracer, error) {
|
|||
return nil, err
|
||||
}
|
||||
if !result.IsFunction() {
|
||||
return nil, fmt.Errorf("Trace object must expose a function result()")
|
||||
return nil, errTraceMustExposeFunctionResult
|
||||
}
|
||||
|
||||
// Create the persistent log object
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
package les
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
|
@ -132,14 +132,16 @@ func lesTopic(genesisHash common.Hash) discv5.Topic {
|
|||
|
||||
type LightDummyAPI struct{}
|
||||
|
||||
var errNotSupported = errors.New("not supported")
|
||||
|
||||
// Etherbase is the address that mining rewards will be send to
|
||||
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)
|
||||
func (s *LightDummyAPI) Coinbase() (common.Address, error) {
|
||||
return common.Address{}, fmt.Errorf("not supported")
|
||||
return common.Address{}, errNotSupported
|
||||
}
|
||||
|
||||
// Hashrate returns the POW hashrate
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package miner
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sync"
|
||||
|
|
@ -487,10 +488,14 @@ func (self *worker) commitNewWork() {
|
|||
self.push(work)
|
||||
}
|
||||
|
||||
var (
|
||||
errUncleNotUnique = errors.New("uncle not unique")
|
||||
)
|
||||
|
||||
func (self *worker) commitUncle(work *Work, uncle *types.Header) error {
|
||||
hash := uncle.Hash()
|
||||
if work.uncles.Has(hash) {
|
||||
return fmt.Errorf("uncle not unique")
|
||||
return errUncleNotUnique
|
||||
}
|
||||
if !work.ancestors.Has(uncle.ParentHash) {
|
||||
return fmt.Errorf("uncle's parent unknown (%x)", uncle.ParentHash[0:4])
|
||||
|
|
|
|||
10
node/api.go
10
node/api.go
|
|
@ -17,6 +17,7 @@
|
|||
package node
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -115,13 +116,18 @@ func (api *PrivateAdminAPI) StartRPC(host *string, port *int, cors *string, apis
|
|||
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.
|
||||
func (api *PrivateAdminAPI) StopRPC() (bool, error) {
|
||||
api.node.lock.Lock()
|
||||
defer api.node.lock.Unlock()
|
||||
|
||||
if api.node.httpHandler == nil {
|
||||
return false, fmt.Errorf("HTTP RPC not running")
|
||||
return false, errHTTPRPCNotRunning
|
||||
}
|
||||
api.node.stopHTTP()
|
||||
return true, nil
|
||||
|
|
@ -175,7 +181,7 @@ func (api *PrivateAdminAPI) StopWS() (bool, error) {
|
|||
defer api.node.lock.Unlock()
|
||||
|
||||
if api.node.wsHandler == nil {
|
||||
return false, fmt.Errorf("WebSocket RPC not running")
|
||||
return false, errWebsocketRPCNotRunning
|
||||
}
|
||||
api.node.stopWS()
|
||||
return true, nil
|
||||
|
|
|
|||
|
|
@ -1052,6 +1052,10 @@ func (net *Network) handle(n *Node, ev nodeEvent, pkt *ingressPacket) error {
|
|||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
errPongReplyMismatch = errors.New("pong reply token mismatch")
|
||||
)
|
||||
|
||||
func (net *Network) checkPacket(n *Node, ev nodeEvent, pkt *ingressPacket) error {
|
||||
// Replay prevention checks.
|
||||
switch ev {
|
||||
|
|
@ -1061,7 +1065,7 @@ func (net *Network) checkPacket(n *Node, ev nodeEvent, pkt *ingressPacket) error
|
|||
case pongPacket:
|
||||
if !bytes.Equal(pkt.data.(*pong).ReplyTok, n.pingEcho) {
|
||||
// fmt.Println("pong reply token mismatch")
|
||||
return fmt.Errorf("pong reply token mismatch")
|
||||
return errPongReplyMismatch
|
||||
}
|
||||
n.pingEcho = nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package discv5
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
|
|
@ -88,13 +89,15 @@ func (ref ticketRef) topicRegTime() mclock.AbsTime {
|
|||
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) {
|
||||
wps := p.data.(*pong).WaitPeriods
|
||||
if 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 {
|
||||
return nil, fmt.Errorf("bad topic hash")
|
||||
return nil, errBadTopicHash
|
||||
}
|
||||
t := &ticket{
|
||||
issueTime: localTime,
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package nat
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
|
@ -44,9 +45,11 @@ func (n *pmp) ExternalIP() (net.IP, error) {
|
|||
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 {
|
||||
if lifetime <= 0 {
|
||||
return fmt.Errorf("lifetime must not be <= 0")
|
||||
return errPositiveLifetime
|
||||
}
|
||||
// Note order of port arguments is switched between our
|
||||
// AddMapping and the client's AddPortMapping.
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package p2p
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
|
|
@ -333,6 +334,10 @@ type protoRW struct {
|
|||
w MsgWriter
|
||||
}
|
||||
|
||||
var (
|
||||
errShuttingDown = errors.New("shutting down")
|
||||
)
|
||||
|
||||
func (rw *protoRW) WriteMsg(msg Msg) (err error) {
|
||||
if msg.Code >= rw.Length {
|
||||
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.
|
||||
rw.werr <- err
|
||||
case <-rw.closed:
|
||||
err = fmt.Errorf("shutting down")
|
||||
err = errShuttingDown
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,13 +130,18 @@ func (t *rlpx) doProtoHandshake(our *protoHandshake) (their *protoHandshake, err
|
|||
return their, nil
|
||||
}
|
||||
|
||||
var (
|
||||
errMessageTooBig = errors.New("message too big")
|
||||
errInvalidPublicKey = errors.New("invalid public key")
|
||||
)
|
||||
|
||||
func readProtocolHandshake(rw MsgReader, our *protoHandshake) (*protoHandshake, error) {
|
||||
msg, err := rw.ReadMsg()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if msg.Size > baseProtocolMaxMsgSize {
|
||||
return nil, fmt.Errorf("message too big")
|
||||
return nil, errMessageTooBig
|
||||
}
|
||||
if msg.Code == discMsg {
|
||||
// Disconnect before protocol handshake is valid according to the
|
||||
|
|
@ -515,7 +520,7 @@ func importPublicKey(pubKey []byte) (*ecies.PublicKey, error) {
|
|||
// TODO: fewer pointless conversions
|
||||
pub := crypto.ToECDSAPub(pubKey65)
|
||||
if pub.X == nil {
|
||||
return nil, fmt.Errorf("invalid public key")
|
||||
return nil, errInvalidPublicKey
|
||||
}
|
||||
return ecies.ImportECDSAPublic(pub), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ package p2p
|
|||
import (
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
|
@ -339,20 +338,25 @@ func (srv *Server) Stop() {
|
|||
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.
|
||||
// Servers can not be re-used after stopping.
|
||||
func (srv *Server) Start() (err error) {
|
||||
srv.lock.Lock()
|
||||
defer srv.lock.Unlock()
|
||||
if srv.running {
|
||||
return errors.New("server already running")
|
||||
return errServerAlreadyRunning
|
||||
}
|
||||
srv.running = true
|
||||
log.Info("Starting P2P networking")
|
||||
|
||||
// static fields
|
||||
if srv.PrivateKey == nil {
|
||||
return fmt.Errorf("Server.PrivateKey must be set to a non-nil key")
|
||||
return errNilServerPrivateKey
|
||||
}
|
||||
if srv.newTransport == nil {
|
||||
srv.newTransport = newRLPX
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package rlp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
|
|
@ -428,9 +429,13 @@ func writeBigIntNoPtr(val reflect.Value, w *encbuf) error {
|
|||
return writeBigInt(&i, w)
|
||||
}
|
||||
|
||||
var (
|
||||
errRLPEncodeNegativeBigInt = errors.New("rlp: cannot encode negative *big.Int")
|
||||
)
|
||||
|
||||
func writeBigInt(i *big.Int, w *encbuf) error {
|
||||
if cmp := i.Cmp(big0); cmp == -1 {
|
||||
return fmt.Errorf("rlp: cannot encode negative *big.Int")
|
||||
return errRLPEncodeNegativeBigInt
|
||||
} else if cmp == 0 {
|
||||
w.str = append(w.str, 0x80)
|
||||
} else {
|
||||
|
|
|
|||
10
rpc/json.go
10
rpc/json.go
|
|
@ -19,6 +19,7 @@ package rpc
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
|
|
@ -134,11 +135,16 @@ func (c *jsonCodec) ReadRequestHeaders() ([]rpcRequest, bool, Error) {
|
|||
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.
|
||||
// valid id's are strings, numbers or null
|
||||
func checkReqId(reqId json.RawMessage) error {
|
||||
if len(reqId) == 0 {
|
||||
return fmt.Errorf("missing request id")
|
||||
return errMissingRequestID
|
||||
}
|
||||
if _, err := strconv.ParseFloat(string(reqId), 64); err == nil {
|
||||
return nil
|
||||
|
|
@ -147,7 +153,7 @@ func checkReqId(reqId json.RawMessage) error {
|
|||
if err := json.Unmarshal(reqId, &str); err == nil {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("invalid request id")
|
||||
return errInvalidRequestID
|
||||
}
|
||||
|
||||
// parseRequest will parse a single request from the given RawMessage. It will return
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
package rpc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"math"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
|
@ -124,6 +124,10 @@ const (
|
|||
EarliestBlockNumber = BlockNumber(0)
|
||||
)
|
||||
|
||||
var (
|
||||
errBlockNumberTooHigh = errors.New("Blocknumber too high")
|
||||
)
|
||||
|
||||
// UnmarshalJSON parses the given JSON fragment into a BlockNumber. It supports:
|
||||
// - "latest", "earliest" or "pending" as string arguments
|
||||
// - the block number
|
||||
|
|
@ -153,7 +157,7 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error {
|
|||
return err
|
||||
}
|
||||
if blckNum > math.MaxInt64 {
|
||||
return fmt.Errorf("Blocknumber too high")
|
||||
return errBlockNumberTooHigh
|
||||
}
|
||||
|
||||
*bn = BlockNumber(blckNum)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package api
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
|
@ -41,6 +42,12 @@ func NewFileSystem(api *Api) *FileSystem {
|
|||
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
|
||||
// using dpa store
|
||||
// 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 {
|
||||
if (err == nil) && !info.IsDir() {
|
||||
if len(path) <= start {
|
||||
return fmt.Errorf("Path is too short")
|
||||
return errPathTooShort
|
||||
}
|
||||
if path[:start] != 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)
|
||||
start = len(dir)
|
||||
if len(localpath) <= start {
|
||||
return "", fmt.Errorf("Path is too short")
|
||||
return "", errPathTooShort
|
||||
}
|
||||
if localpath[:start] != 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:
|
||||
wg.Add(1)
|
||||
case <-quitC:
|
||||
return fmt.Errorf("aborted")
|
||||
return errAborted
|
||||
}
|
||||
go func(i int, entry *downloadListEntry) {
|
||||
defer wg.Done()
|
||||
|
|
@ -263,7 +270,7 @@ func (self *FileSystem) Download(bzzpath, localpath string) error {
|
|||
case err = <-errC:
|
||||
return err
|
||||
case <-quitC:
|
||||
return fmt.Errorf("aborted")
|
||||
return errAborted
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ func readManifest(manifestReader storage.LazySectionReader, hash storage.Key, dp
|
|||
size, err := manifestReader.Size(quitC)
|
||||
if err != nil { // size == 0
|
||||
// can't determine size means we don't have the root chunk
|
||||
err = fmt.Errorf("Manifest not Found")
|
||||
err = errManifestNotFound
|
||||
return
|
||||
}
|
||||
manifestData := make([]byte, size)
|
||||
|
|
@ -379,7 +379,7 @@ func (self *manifestTrie) listWithPrefixInt(prefix, rp string, quitC chan bool,
|
|||
for i := start; i <= stop; i++ {
|
||||
select {
|
||||
case <-quitC:
|
||||
return fmt.Errorf("aborted")
|
||||
return errAborted
|
||||
default:
|
||||
}
|
||||
entry := self.entries[i]
|
||||
|
|
|
|||
|
|
@ -20,13 +20,17 @@ package fuse
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"errors"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
|
||||
var (
|
||||
errUnmountUnimplemented = errors.New("unmount: unimplemented")
|
||||
)
|
||||
|
||||
func externalUnmount(mountPoint string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), unmountTimeout)
|
||||
defer cancel()
|
||||
|
|
@ -42,7 +46,7 @@ func externalUnmount(mountPoint string) error {
|
|||
case "linux":
|
||||
return exec.CommandContext(ctx, "fusermount", "-u", mountPoint).Run()
|
||||
default:
|
||||
return fmt.Errorf("unmount: unimplemented")
|
||||
return errUnmountUnimplemented
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package network
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"path/filepath"
|
||||
|
|
@ -317,12 +318,16 @@ func (self *peer) LastActive() time.Time {
|
|||
return self.lastActive
|
||||
}
|
||||
|
||||
var (
|
||||
errInvalidType = errors.New("invalid type")
|
||||
)
|
||||
|
||||
// reads the serialised form of sync state persisted as the 'Meta' attribute
|
||||
// and sets the decoded syncState on the online node
|
||||
func loadSync(record *kademlia.NodeRecord, node kademlia.Node) error {
|
||||
p, ok := node.(*peer)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid type")
|
||||
return errInvalidType
|
||||
}
|
||||
if record.Meta == nil {
|
||||
log.Debug(fmt.Sprintf("no sync state for node record %v setting default", record))
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package kademlia
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
|
@ -113,6 +114,10 @@ func (self *Kademlia) DBCount() int {
|
|||
return self.db.count()
|
||||
}
|
||||
|
||||
var (
|
||||
errBucketFull = errors.New("bucket full")
|
||||
)
|
||||
|
||||
// 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)
|
||||
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 {
|
||||
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))
|
||||
replaced.Drop()
|
||||
|
|
|
|||
|
|
@ -183,6 +183,11 @@ func (self *bzz) Drop() {
|
|||
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
|
||||
func (self *bzz) handle() error {
|
||||
msg, err := self.rw.ReadMsg()
|
||||
|
|
@ -230,7 +235,7 @@ func (self *bzz) handle() error {
|
|||
if req.isLookup() {
|
||||
log.Trace(fmt.Sprintf("self lookup for %v: responding with peers only...", req.from))
|
||||
} else if req.Key == nil {
|
||||
return fmt.Errorf("protocol handler: req.Key == nil || req.Timeout == nil")
|
||||
return errProtocolHandlerNilReqKey
|
||||
} else {
|
||||
// swap accounting is done within netStore
|
||||
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 {
|
||||
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))
|
||||
err := p2p.Send(self.rw, msg, data)
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package network
|
|||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
|
|
@ -230,13 +231,17 @@ func encodeSync(state *syncState) (*json.RawMessage, error) {
|
|||
return &meta, nil
|
||||
}
|
||||
|
||||
var (
|
||||
errDecodeNilSyncState = errors.New("unable to deserialise sync state from <nil>")
|
||||
)
|
||||
|
||||
func decodeSync(meta *json.RawMessage) (*syncState, error) {
|
||||
if meta == nil {
|
||||
return nil, fmt.Errorf("unable to deserialise sync state from <nil>")
|
||||
return nil, errDecodeNilSyncState
|
||||
}
|
||||
data := []byte(*(meta))
|
||||
if len(data) == 0 {
|
||||
return nil, fmt.Errorf("unable to deserialise sync state from <nil>")
|
||||
return nil, errDecodeNilSyncState
|
||||
}
|
||||
state := &syncState{DbSyncState: &storage.DbSyncState{}}
|
||||
err := json.Unmarshal(data, state)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import (
|
|||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
|
@ -550,10 +551,14 @@ type dbSyncIterator struct {
|
|||
DbSyncState
|
||||
}
|
||||
|
||||
var (
|
||||
errNoEntriesFound = errors.New("no entries found")
|
||||
)
|
||||
|
||||
// initialises a sync iterator from a syncToken (passed in with the handshake)
|
||||
func (self *DbStore) NewSyncIterator(state DbSyncState) (si *dbSyncIterator, err error) {
|
||||
if state.First > state.Last {
|
||||
return nil, fmt.Errorf("no entries found")
|
||||
return nil, errNoEntriesFound
|
||||
}
|
||||
si = &dbSyncIterator{
|
||||
it: self.db.NewIterator(),
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
"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
|
||||
// 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) {
|
||||
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) {
|
||||
return nil, fmt.Errorf("empty bzz key")
|
||||
return nil, errEmptyBzzKey
|
||||
}
|
||||
|
||||
self = &Swarm{
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package whisperv2
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
|
@ -243,6 +244,12 @@ func (args *PostArgs) UnmarshalJSON(data []byte) (err error) {
|
|||
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
|
||||
// JSON message blob into a WhisperFilterArgs structure.
|
||||
func (args *NewFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
|
|
@ -262,7 +269,7 @@ func (args *NewFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
} else {
|
||||
argstr, ok := obj.To.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("to is not a string")
|
||||
return errToNotAString
|
||||
}
|
||||
args.To = argstr
|
||||
}
|
||||
|
|
@ -271,7 +278,7 @@ func (args *NewFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
} else {
|
||||
argstr, ok := obj.From.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("from is not a string")
|
||||
return errFromNotAString
|
||||
}
|
||||
args.From = argstr
|
||||
}
|
||||
|
|
@ -280,7 +287,7 @@ func (args *NewFilterArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
// Make sure we have an actual topic array
|
||||
list, ok := obj.Topics.([]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("topics is not an array")
|
||||
return errTopicsNotArray
|
||||
}
|
||||
// Iterate over each topic and handle nil, string or array
|
||||
topics := make([][]string, len(list))
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ package whisperv2
|
|||
import (
|
||||
"crypto/ecdsa"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"time"
|
||||
|
|
@ -84,6 +85,10 @@ func (self *Envelope) rlpWithoutNonce() []byte {
|
|||
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.
|
||||
func (self *Envelope) Open(key *ecdsa.PrivateKey) (msg *Message, err error) {
|
||||
// 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 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:]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"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.
|
||||
func selfSend(shh *whisper.Whisper, payload []byte) error {
|
||||
ok := make(chan struct{})
|
||||
|
|
@ -100,7 +103,7 @@ func selfSend(shh *whisper.Whisper, payload []byte) error {
|
|||
select {
|
||||
case <-ok:
|
||||
case <-time.After(time.Second):
|
||||
return fmt.Errorf("failed to receive message in time")
|
||||
return errMsgRecvTimedout
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ func (api *PublicWhisperAPI) Info(ctx context.Context) Info {
|
|||
stats := api.w.Stats()
|
||||
return Info{
|
||||
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(),
|
||||
MaxMessageSize: api.w.MaxMessageSize(),
|
||||
}
|
||||
|
|
@ -489,6 +489,10 @@ func toMessage(messages []*ReceivedMessage) []*Message {
|
|||
return msgs
|
||||
}
|
||||
|
||||
var (
|
||||
errFilterNotFound = errors.New("filter not found")
|
||||
)
|
||||
|
||||
// GetFilterMessages returns the messages that match the filter criteria and
|
||||
// are received between the last poll and now.
|
||||
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)
|
||||
if f == nil {
|
||||
api.mu.Unlock()
|
||||
return nil, fmt.Errorf("filter not found")
|
||||
return nil, errFilterNotFound
|
||||
}
|
||||
api.lastUsed[id] = time.Now()
|
||||
api.mu.Unlock()
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ func (fs *Filters) Install(watcher *Filter) (string, error) {
|
|||
defer fs.mutex.Unlock()
|
||||
|
||||
if fs.watchers[id] != nil {
|
||||
return "", fmt.Errorf("failed to generate unique ID")
|
||||
return "", errFailedToGenerateUniqueID
|
||||
}
|
||||
|
||||
fs.watchers[id] = watcher
|
||||
|
|
|
|||
|
|
@ -236,6 +236,22 @@ func (w *Whisper) SendP2PDirect(peer *Peer, envelope *Envelope) error {
|
|||
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
|
||||
// it into the known identities for message decryption. Returns ID of the new key pair.
|
||||
func (w *Whisper) NewKeyPair() (string, error) {
|
||||
|
|
@ -247,7 +263,7 @@ func (w *Whisper) NewKeyPair() (string, error) {
|
|||
return "", err
|
||||
}
|
||||
if !validatePrivateKey(key) {
|
||||
return "", fmt.Errorf("failed to generate valid key")
|
||||
return "", errFailedToGenerateValidKey
|
||||
}
|
||||
|
||||
id, err := GenerateRandomID()
|
||||
|
|
@ -259,7 +275,7 @@ func (w *Whisper) NewKeyPair() (string, error) {
|
|||
defer w.keyMu.Unlock()
|
||||
|
||||
if w.privateKeys[id] != nil {
|
||||
return "", fmt.Errorf("failed to generate unique ID")
|
||||
return "", errFailedToGenerateUniqueID
|
||||
}
|
||||
w.privateKeys[id] = key
|
||||
return id, nil
|
||||
|
|
@ -305,7 +321,7 @@ func (w *Whisper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) {
|
|||
defer w.keyMu.RUnlock()
|
||||
key := w.privateKeys[id]
|
||||
if key == nil {
|
||||
return nil, fmt.Errorf("invalid id")
|
||||
return nil, errInvalidID
|
||||
}
|
||||
return key, nil
|
||||
}
|
||||
|
|
@ -318,7 +334,7 @@ func (w *Whisper) GenerateSymKey() (string, error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
} else if !validateSymmetricKey(key) {
|
||||
return "", fmt.Errorf("error in GenerateSymKey: crypto/rand failed to generate random data")
|
||||
return "", errGenSymKeyRandomData
|
||||
}
|
||||
|
||||
id, err := GenerateRandomID()
|
||||
|
|
@ -330,7 +346,7 @@ func (w *Whisper) GenerateSymKey() (string, error) {
|
|||
defer w.keyMu.Unlock()
|
||||
|
||||
if w.symKeys[id] != nil {
|
||||
return "", fmt.Errorf("failed to generate unique ID")
|
||||
return "", errFailedToGenerateUniqueID
|
||||
}
|
||||
w.symKeys[id] = key
|
||||
return id, nil
|
||||
|
|
@ -351,7 +367,7 @@ func (w *Whisper) AddSymKeyDirect(key []byte) (string, error) {
|
|||
defer w.keyMu.Unlock()
|
||||
|
||||
if w.symKeys[id] != nil {
|
||||
return "", fmt.Errorf("failed to generate unique ID")
|
||||
return "", errFailedToGenerateUniqueID
|
||||
}
|
||||
w.symKeys[id] = key
|
||||
return id, nil
|
||||
|
|
@ -364,7 +380,7 @@ func (w *Whisper) AddSymKeyFromPassword(password string) (string, error) {
|
|||
return "", fmt.Errorf("failed to generate ID: %s", err)
|
||||
}
|
||||
if w.HasSymKey(id) {
|
||||
return "", fmt.Errorf("failed to generate unique ID")
|
||||
return "", errFailedToGenerateUniqueID
|
||||
}
|
||||
|
||||
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
|
||||
if w.symKeys[id] != nil {
|
||||
return "", fmt.Errorf("critical error: failed to generate unique ID")
|
||||
return "", errCriticalFailedToGenerateUniqueID
|
||||
}
|
||||
w.symKeys[id] = derived
|
||||
return id, nil
|
||||
|
|
@ -409,7 +425,7 @@ func (w *Whisper) GetSymKey(id string) ([]byte, error) {
|
|||
if 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
|
||||
|
|
@ -427,7 +443,7 @@ func (w *Whisper) GetFilter(id string) *Filter {
|
|||
func (w *Whisper) Unsubscribe(id string) error {
|
||||
ok := w.filters.Uninstall(id)
|
||||
if !ok {
|
||||
return fmt.Errorf("Unsubscribe: Invalid ID")
|
||||
return errUnsubscribeInvalidID
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -440,7 +456,7 @@ func (w *Whisper) Send(envelope *Envelope) error {
|
|||
return err
|
||||
}
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to add envelope")
|
||||
return errFailedToAddEnvelope
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
@ -535,7 +551,7 @@ func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
|
|||
var envelope Envelope
|
||||
if err := packet.Decode(&envelope); err != nil {
|
||||
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)
|
||||
}
|
||||
|
|
@ -545,7 +561,7 @@ func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
|
|||
var request Envelope
|
||||
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)
|
||||
return errors.New("invalid p2p request")
|
||||
return errInvalidP2PRequest
|
||||
}
|
||||
wh.mailServer.DeliverMail(p, &request)
|
||||
}
|
||||
|
|
@ -576,7 +592,7 @@ func (wh *Whisper) add(envelope *Envelope) (bool, error) {
|
|||
|
||||
if envelope.Expiry < now {
|
||||
if envelope.Expiry+SynchAllowance*2 < now {
|
||||
return false, fmt.Errorf("very old message")
|
||||
return false, errVeryOldMessage
|
||||
} else {
|
||||
log.Debug("expired envelope dropped", "hash", envelope.Hash().Hex())
|
||||
return false, nil // drop envelope without error
|
||||
|
|
@ -851,7 +867,7 @@ func GenerateRandomID() (id string, err error) {
|
|||
return "", err
|
||||
}
|
||||
if !validateSymmetricKey(buf) {
|
||||
return "", fmt.Errorf("error in generateRandomID: crypto/rand failed to generate random data")
|
||||
return "", errGenRandomIDRandomData
|
||||
}
|
||||
id = common.Bytes2Hex(buf)
|
||||
return id, err
|
||||
|
|
|
|||
Loading…
Reference in a new issue