code.vegaprotocol.io/vega@v0.79.0/wallet/api/errors.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package api
    17  
    18  import (
    19  	"context"
    20  	"errors"
    21  	"fmt"
    22  
    23  	"code.vegaprotocol.io/vega/libs/jsonrpc"
    24  	"code.vegaprotocol.io/vega/wallet/api/node/types"
    25  )
    26  
    27  const (
    28  	// Implementation-defined server-errors.
    29  
    30  	// ErrorCodeRequestHasBeenInterrupted refers to a request that has been
    31  	// interrupted by the server or the third-party application. It could
    32  	// originate from a timeout or an explicit cancellation.
    33  	ErrorCodeRequestHasBeenInterrupted jsonrpc.ErrorCode = -32001
    34  
    35  	// ErrorCodeHostnameResolutionFailure refers to the inability for the server
    36  	// to resolve the hostname from the request.
    37  	ErrorCodeHostnameResolutionFailure jsonrpc.ErrorCode = -32002
    38  
    39  	// ErrorCodeAuthenticationFailure refers to a request that have authentication
    40  	// problems.
    41  	ErrorCodeAuthenticationFailure jsonrpc.ErrorCode = -32003
    42  
    43  	// Network error codes are errors that comes from the network itself and its
    44  	// nodes. It ranges from 1000 to 1999, included.
    45  	// Apart from the communication failure, network errors are valued based on
    46  	// their ABCI code counter-part:
    47  	//     Network_Error_Code == ABCI_Error_Code + 1000
    48  
    49  	// ErrorCodeNodeCommunicationFailed refers to the inability of the program to
    50  	// talk to the network nodes.
    51  	ErrorCodeNodeCommunicationFailed jsonrpc.ErrorCode = 1000
    52  
    53  	// ErrorCodeNetworkRejectedTransaction refers to a transaction rejected by
    54  	// the network nodes but for an unknown ABCI code.
    55  	ErrorCodeNetworkRejectedTransaction jsonrpc.ErrorCode = 1001
    56  
    57  	// ErrorCodeNetworkRejectedInvalidTransaction refers to a validation failure raised
    58  	// by the network nodes (error code 51).
    59  	ErrorCodeNetworkRejectedInvalidTransaction jsonrpc.ErrorCode = 1051
    60  
    61  	// ErrorCodeNetworkRejectedMalformedTransaction refers to the inability to
    62  	// decode a transaction from the network nodes (error code 60).
    63  	ErrorCodeNetworkRejectedMalformedTransaction jsonrpc.ErrorCode = 1060
    64  
    65  	// ErrorCodeNetworkCouldNotProcessTransaction refers to the inability to
    66  	// process a transaction from the network nodes (error code 70).
    67  	ErrorCodeNetworkCouldNotProcessTransaction jsonrpc.ErrorCode = 1070
    68  
    69  	// ErrorCodeNetworkRejectedUnsupportedTransaction is raised when the network
    70  	// nodes encounter an unsupported transaction (error code 80).
    71  	ErrorCodeNetworkRejectedUnsupportedTransaction jsonrpc.ErrorCode = 1080
    72  
    73  	// ErrorCodeNetworkSpamProtectionActivated is raised when the network
    74  	// nodes spin up the spam protection mechanism (error code 89).
    75  	ErrorCodeNetworkSpamProtectionActivated jsonrpc.ErrorCode = 1089
    76  
    77  	// Application error codes are programmatic errors that comes from the API
    78  	// itself and its "business" rules. It ranges from 2000 to 2999, included.
    79  
    80  	// ErrorCodeRequestNotPermitted refers a request made by a third-party application
    81  	// that is not permitted to do. This error is related to the permissions'
    82  	// system.
    83  	ErrorCodeRequestNotPermitted jsonrpc.ErrorCode = 2000
    84  
    85  	// ErrorCodeRequestHasBeenCancelledByApplication refers to an automated
    86  	// cancellation of a request by the application core. This happens when some
    87  	// requirements are missing to ensure correct handling of a request.
    88  	ErrorCodeRequestHasBeenCancelledByApplication jsonrpc.ErrorCode = 2001
    89  
    90  	// User error codes are errors that results from the user. It ranges
    91  	// from 3000 to 3999, included.
    92  
    93  	// ErrorCodeConnectionHasBeenClosed refers to an interruption of the service
    94  	// triggered by the user.
    95  	ErrorCodeConnectionHasBeenClosed jsonrpc.ErrorCode = 3000
    96  
    97  	// ErrorCodeRequestHasBeenRejected refers to an explicit rejection of a
    98  	// request by the user. When received, the third-party application should
    99  	// consider the user has withdrawn from the action, and thus, abort the
   100  	// action.
   101  	ErrorCodeRequestHasBeenRejected jsonrpc.ErrorCode = 3001
   102  
   103  	// ErrorCodeRequestHasBeenCancelledByUser refers to a cancellation of a
   104  	// request by the user. It's conceptually different from a rejection.
   105  	// Contrary to a rejection, when a cancellation is received, the third-party
   106  	// application should temporarily back off, maintain its state, and wait for
   107  	// the user to be ready to continue.
   108  	ErrorCodeRequestHasBeenCancelledByUser jsonrpc.ErrorCode = 3002
   109  )
   110  
   111  var (
   112  	ErrApplicationCancelledTheRequest                     = errors.New("the application cancelled the request")
   113  	ErrBlockHashIsRequired                                = errors.New("the block hash is required")
   114  	ErrBlockHeightIsRequired                              = errors.New("the block height is required")
   115  	ErrBlockHeightTooHistoric                             = errors.New("the block height is too historic")
   116  	ErrCannotRotateKeysOnIsolatedWallet                   = errors.New("cannot rotate keys on an isolated wallet")
   117  	ErrChainIDIsRequired                                  = errors.New("the chain ID is required")
   118  	ErrConnectionClosed                                   = errors.New("the connection has been closed")
   119  	ErrCouldNotCheckTransaction                           = errors.New("could not check transaction")
   120  	ErrCouldNotConnectToWallet                            = errors.New("could not connect to the wallet")
   121  	ErrCouldNotGetChainIDFromNode                         = errors.New("could not get the chain ID from the node")
   122  	ErrCouldNotGetLastBlockInformation                    = errors.New("could not get information about the last block on the network")
   123  	ErrCouldNotGetSpamStatistics                          = errors.New("could not get latest spam statistics for the public key on the network")
   124  	ErrCouldNotListKeys                                   = errors.New("could not list the keys")
   125  	ErrCouldNotSendTransaction                            = errors.New("could not send transaction")
   126  	ErrCouldNotSignTransaction                            = errors.New("could not sign transaction")
   127  	ErrCurrentPublicKeyDoesNotExist                       = errors.New("the current public key does not exist")
   128  	ErrCurrentPublicKeyIsRequired                         = errors.New("the next public key is required")
   129  	ErrEnactmentBlockHeightIsRequired                     = errors.New("the enactment block height is required")
   130  	ErrEnactmentBlockHeightMustBeGreaterThanSubmissionOne = errors.New("the enactment block height must be greater than the submission one")
   131  	ErrEncodedMessageIsNotValidBase64String               = errors.New("the encoded message is not a valid base-64 string")
   132  	ErrEncodedSignatureIsNotValidBase64String             = errors.New("the encoded signature is not a valid base-64 string")
   133  	ErrEncodedTransactionIsNotValidBase64String           = errors.New("the encoded transaction is not a valid base-64 string")
   134  	ErrEncodedTransactionIsRequired                       = errors.New("the encoded transaction is required")
   135  	ErrHostnameIsRequired                                 = errors.New("the hostname is required")
   136  	ErrIsolatedWalletPassphraseIsRequired                 = errors.New("the isolated wallet passphrase is required")
   137  	ErrLastBlockDataOrNetworkIsRequired                   = errors.New("a network or the last block data is required")
   138  	ErrMessageIsRequired                                  = errors.New("the message is required")
   139  	ErrNetworkAlreadyExists                               = errors.New("a network with the same name already exists")
   140  	ErrNetworkConfigurationDoesNotHaveGRPCNodes           = errors.New("the network does not have gRPC hosts configured")
   141  	ErrNetworkDoesNotExist                                = errors.New("the network does not exist")
   142  	ErrNetworkIsRequired                                  = errors.New("the network is required")
   143  	ErrNetworkNameIsRequired                              = errors.New("the network name is required")
   144  	ErrNetworkOrNodeAddressIsRequired                     = errors.New("a network or a node address is required")
   145  	ErrNetworkSourceIsRequired                            = errors.New("a network source is required")
   146  	ErrNewNameIsRequired                                  = errors.New("the new name is required")
   147  	ErrNewPassphraseIsRequired                            = errors.New("the new passphrase is required")
   148  	ErrNextAndCurrentPublicKeysCannotBeTheSame            = errors.New("the next and current public keys cannot be the same")
   149  	ErrNextPublicKeyDoesNotExist                          = errors.New("the next public key does not exist")
   150  	ErrNextPublicKeyIsRequired                            = errors.New("the next public key is required")
   151  	ErrNextPublicKeyIsTainted                             = errors.New("the next public key is tainted")
   152  	ErrNoHealthyNodeAvailable                             = errors.New("no healthy node available")
   153  	ErrNoWalletToConnectTo                                = errors.New("there is no wallet to connect to, you should, first, create or import a wallet")
   154  	ErrParamsDoNotMatch                                   = errors.New("the params do not match expected ones")
   155  	ErrParamsRequired                                     = errors.New("the params are required")
   156  	ErrPassphraseIsRequired                               = errors.New("the passphrase is required")
   157  	ErrProofOfWorkDifficultyRequired                      = errors.New("the proof-of-work difficulty is required")
   158  	ErrProofOfWorkHashFunctionRequired                    = errors.New("the proof-of-work hash function is required")
   159  	ErrPublicKeyDoesNotExist                              = errors.New("the public key does not exist")
   160  	ErrPublicKeyIsNotAllowedToBeUsed                      = errors.New("this public key is not allowed to be used")
   161  	ErrPublicKeyIsRequired                                = errors.New("the public key is required")
   162  	ErrRawTransactionIsNotValidVegaTransaction            = errors.New("the raw transaction is not a valid Vega transaction")
   163  	ErrRecoveryPhraseIsRequired                           = errors.New("the recovery phrase is required")
   164  	ErrRequestCancelled                                   = errors.New("the request has been cancelled")
   165  	ErrRequestInterrupted                                 = errors.New("the request has been interrupted")
   166  	ErrSendingModeCannotBeTypeUnspecified                 = errors.New(`the sending mode can't be "TYPE_UNSPECIFIED"`)
   167  	ErrSendingModeIsRequired                              = errors.New("the sending mode is required")
   168  	ErrSignatureIsRequired                                = errors.New("the signature is required")
   169  	ErrSpecifyingNetworkAndLastBlockDataIsNotSupported    = errors.New("specifying a network and the last block data is not supported")
   170  	ErrSpecifyingNetworkAndNodeAddressIsNotSupported      = errors.New("specifying a network and a node address is not supported")
   171  	ErrSubmissionBlockHeightIsRequired                    = errors.New("the submission block height is required")
   172  	ErrTransactionIsNotValidJSON                          = errors.New("the transaction is not valid JSON")
   173  	ErrTransactionIsRequired                              = errors.New("the transaction is required")
   174  	ErrTransactionsPerBlockLimitReached                   = errors.New("the transaction per block limit has been reached")
   175  	ErrUserCancelledTheRequest                            = errors.New("the user cancelled the request")
   176  	ErrUserCloseTheConnection                             = errors.New("the user closed the connection")
   177  	ErrUserRejectedAccessToKeys                           = errors.New("the user rejected the access to the keys")
   178  	ErrUserRejectedCheckingOfTransaction                  = errors.New("the user rejected the checking of the transaction")
   179  	ErrUserRejectedSendingOfTransaction                   = errors.New("the user rejected the sending of the transaction")
   180  	ErrUserRejectedSigningOfTransaction                   = errors.New("the user rejected the signing of the transaction")
   181  	ErrUserRejectedWalletConnection                       = errors.New("the user rejected the wallet connection")
   182  	ErrWalletAlreadyExists                                = errors.New("a wallet with the same name already exists")
   183  	ErrWalletDoesNotExist                                 = errors.New("the wallet does not exist")
   184  	ErrWalletIsLocked                                     = errors.New("the wallet is locked")
   185  	ErrWalletIsRequired                                   = errors.New("the wallet is required")
   186  	ErrWalletKeyDerivationVersionIsRequired               = errors.New("the wallet key derivation version is required")
   187  )
   188  
   189  func ApplicationError(code jsonrpc.ErrorCode, err error) *jsonrpc.ErrorDetails {
   190  	if code <= -32000 {
   191  		panic("application error code should be greater than -32000")
   192  	}
   193  	return jsonrpc.NewCustomError(code, "Application error", err)
   194  }
   195  
   196  func UserError(code jsonrpc.ErrorCode, err error) *jsonrpc.ErrorDetails {
   197  	if code <= -32000 {
   198  		panic("user error code should be greater than -32000")
   199  	}
   200  	return jsonrpc.NewCustomError(code, "User error", err)
   201  }
   202  
   203  func NetworkError(code jsonrpc.ErrorCode, err error) *jsonrpc.ErrorDetails {
   204  	return jsonrpc.NewCustomError(code, "Network error", err)
   205  }
   206  
   207  // NetworkErrorFromTransactionError returns an error with a generic message but
   208  // a specialized code. This is intended to give a coarse-grained indication
   209  // to the third-party application without taking any risk of leaking information
   210  // from the error message.
   211  func NetworkErrorFromTransactionError(err error) *jsonrpc.ErrorDetails {
   212  	txErr := types.TransactionError{}
   213  	isTxErr := errors.As(err, &txErr)
   214  	if !isTxErr {
   215  		return NetworkError(ErrorCodeNodeCommunicationFailed, fmt.Errorf("the transaction failed: %w", err))
   216  	}
   217  
   218  	switch txErr.ABCICode {
   219  	case 51:
   220  		return NetworkError(ErrorCodeNetworkRejectedInvalidTransaction, fmt.Errorf("the network rejected the transaction because it's invalid: %w", err))
   221  	case 60:
   222  		return NetworkError(ErrorCodeNetworkRejectedMalformedTransaction, fmt.Errorf("the network rejected the transaction because it's malformed: %w", err))
   223  	case 70:
   224  		return NetworkError(ErrorCodeNetworkCouldNotProcessTransaction, fmt.Errorf("the network could not process the transaction: %w", err))
   225  	case 80:
   226  		return NetworkError(ErrorCodeNetworkRejectedUnsupportedTransaction, fmt.Errorf("the network does not support this transaction: %w", err))
   227  	case 89:
   228  		return NetworkError(ErrorCodeNetworkSpamProtectionActivated, fmt.Errorf("the network blocked the transaction through the spam protection: %w", err))
   229  	default:
   230  		return NetworkError(ErrorCodeNetworkRejectedTransaction, fmt.Errorf("the transaction failed: %w", err))
   231  	}
   232  }
   233  
   234  func NodeCommunicationError(err error) *jsonrpc.ErrorDetails {
   235  	return NetworkError(ErrorCodeNodeCommunicationFailed, err)
   236  }
   237  
   238  func InvalidParams(err error) *jsonrpc.ErrorDetails {
   239  	return jsonrpc.NewInvalidParams(err)
   240  }
   241  
   242  func RequestInterruptedError(err error) *jsonrpc.ErrorDetails {
   243  	return jsonrpc.NewServerError(ErrorCodeRequestHasBeenInterrupted, err)
   244  }
   245  
   246  func ConnectionClosedError(err error) *jsonrpc.ErrorDetails {
   247  	return UserError(ErrorCodeConnectionHasBeenClosed, err)
   248  }
   249  
   250  func UserCancellationError(err error) *jsonrpc.ErrorDetails {
   251  	return UserError(ErrorCodeRequestHasBeenCancelledByUser, err)
   252  }
   253  
   254  func UserRejectionError(err error) *jsonrpc.ErrorDetails {
   255  	return UserError(ErrorCodeRequestHasBeenRejected, err)
   256  }
   257  
   258  func RequestNotPermittedError(err error) *jsonrpc.ErrorDetails {
   259  	return ApplicationError(ErrorCodeRequestNotPermitted, err)
   260  }
   261  
   262  func ApplicationCancellationError(err error) *jsonrpc.ErrorDetails {
   263  	return ApplicationError(ErrorCodeRequestHasBeenCancelledByApplication, err)
   264  }
   265  
   266  func InternalError(err error) *jsonrpc.ErrorDetails {
   267  	return jsonrpc.NewInternalError(err)
   268  }
   269  
   270  // HandleRequestFlowError is a generic function that build the appropriate
   271  // API error response based on the underlying error.
   272  // If none of them matches, the error handling is delegating to the caller.
   273  func HandleRequestFlowError(ctx context.Context, traceID string, interactor Interactor, err error) *jsonrpc.ErrorDetails {
   274  	if errors.Is(err, ErrUserCancelledTheRequest) {
   275  		// 1. Using a different error message to better fit the front-end needs.
   276  		// 2. Contrary to the response returned to the third-party application,
   277  		//    we notify an ApplicationErrorType to the wallet front-end, so it knows
   278  		//    it has to consider this error as a terminal one.
   279  		interactor.NotifyError(ctx, traceID, ApplicationErrorType, ErrRequestCancelled)
   280  		return UserCancellationError(err)
   281  	}
   282  	if errors.Is(err, ErrUserCloseTheConnection) {
   283  		// 1. Using a different error message to better fit the front-end needs.
   284  		// 2. Contrary to the response returned to the third-party application,
   285  		//    we notify an ApplicationErrorType to the wallet front-end, so it knows
   286  		//    it has to consider this error as a terminal one.
   287  		interactor.NotifyError(ctx, traceID, ApplicationErrorType, ErrConnectionClosed)
   288  		return ConnectionClosedError(err)
   289  	}
   290  	if errors.Is(err, ErrRequestInterrupted) {
   291  		interactor.NotifyError(ctx, traceID, ServerErrorType, err)
   292  		return RequestInterruptedError(err)
   293  	}
   294  	return nil
   295  }