github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/neorpc/errors.go (about)

     1  package neorpc
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  )
     7  
     8  // Error represents JSON-RPC 2.0 error type.
     9  type Error struct {
    10  	Code    int64  `json:"code"`
    11  	Message string `json:"message"`
    12  	Data    string `json:"data,omitempty"`
    13  }
    14  
    15  // Standard RPC error codes defined by the JSON-RPC 2.0 specification.
    16  const (
    17  	// InternalServerErrorCode is returned for internal RPC server error.
    18  	InternalServerErrorCode = -32603
    19  	// BadRequestCode is returned on parse error.
    20  	BadRequestCode = -32700
    21  	// InvalidRequestCode is returned on invalid request.
    22  	InvalidRequestCode = -32600
    23  	// MethodNotFoundCode is returned on unknown method calling.
    24  	MethodNotFoundCode = -32601
    25  	// InvalidParamsCode is returned on request with invalid params.
    26  	InvalidParamsCode = -32602
    27  )
    28  
    29  // RPC error codes defined by the Neo JSON-RPC specification extension.
    30  // Codes for missing items.
    31  const (
    32  	// ErrUnknownBlockCode is returned from a call that accepts as a parameter or searches for a header or a block
    33  	// as a part of its job can't find it.
    34  	ErrUnknownBlockCode = -101
    35  	// ErrUnknownContractCode is returned from a call that accepts as a parameter or searches for a contract
    36  	// as a part of its job can't find it.
    37  	ErrUnknownContractCode = -102
    38  	// ErrUnknownTransactionCode is returned from a call that accepts as a parameter or searches for a transaction
    39  	// as a part of its job can't find it.
    40  	ErrUnknownTransactionCode = -103
    41  	// ErrUnknownStorageItemCode is returned from a call that looks for an item in the contract storage
    42  	// as part of its job can't find it.
    43  	ErrUnknownStorageItemCode = -104
    44  	// ErrUnknownScriptContainerCode is returned from a call that accepts as a parameter or searches for a script
    45  	// container (a block or transaction) as a part of its job can't find it
    46  	// (this error generalizes -101 and -103 in cases where it's needed).
    47  	ErrUnknownScriptContainerCode = -105
    48  	// ErrUnknownStateRootCode is returned from a call that accepts as a parameter or searches for a state root
    49  	// as a part of its job can't find it.
    50  	ErrUnknownStateRootCode = -106
    51  	// ErrUnknownSessionCode is returned from a call that accepts as a parameter or searches for an iterator session
    52  	// as a part of its job can't find it.
    53  	ErrUnknownSessionCode = -107
    54  	// ErrUnknownIteratorCode is returned from a call that accepts as a parameter or searches for a session iterator
    55  	// as a part of its job can't find it.
    56  	ErrUnknownIteratorCode = -108
    57  	// ErrUnknownHeightCode is returned if block or header height passed as parameter or calculated during call
    58  	// execution is not correct (out of the range known to the node).
    59  	ErrUnknownHeightCode = -109
    60  )
    61  
    62  // Codes for calls that use a wallet (-300...-304) can be returned by the C# RPC server only,
    63  // see the https://github.com/nspcc-dev/neo-go/blob/master/docs/rpc.md#unsupported-methods.
    64  const (
    65  	// ErrInsufficientFundsWalletCode is returned if transaction that sends some assets can't be created
    66  	// because it fails. Can be returned only by the C# RPC server.
    67  	ErrInsufficientFundsWalletCode = -300
    68  	// ErrWalletFeeLimitCode is returned if transaction requires more network fee to be paid
    69  	// than is allowed by settings. Can be returned only by the C# RPC server.
    70  	ErrWalletFeeLimitCode = -301
    71  	// ErrNoOpenedWalletCode is returned if server doesn't have any opened wallet to operate with.
    72  	// Can be returned only by the C# RPC server.
    73  	ErrNoOpenedWalletCode = -302
    74  	// ErrWalletNotFoundCode is returned if specified (or configured) wallet file path is invalid.
    75  	// Can be returned only by the C# RPC server.
    76  	ErrWalletNotFoundCode = -303
    77  	// ErrWalletNotSupportedCode is returned if specified (or configured) file can't be opened as a wallet.
    78  	// Can be returned only by the C# RPC server.
    79  	ErrWalletNotSupportedCode = -304
    80  )
    81  
    82  // Inventory verification or verification script errors.
    83  const (
    84  	// ErrVerificationFailedCode is returned on anything that can't be expressed by other codes.
    85  	// It is an unclassified inventory verification error.
    86  	ErrVerificationFailedCode = -500
    87  	// ErrAlreadyExistsCode is returned if block or transaction is already accepted and processed on chain.
    88  	ErrAlreadyExistsCode = -501
    89  	// ErrMempoolCapReachedCode is returned if no more transactions can be accepted into the memory pool
    90  	// (unless they have a priority) as its full capacity is reached.
    91  	ErrMempoolCapReachedCode = -502
    92  	// ErrAlreadyInPoolCode is returned if transaction is already pooled, but not yet accepted into a block.
    93  	ErrAlreadyInPoolCode = -503
    94  	// ErrInsufficientNetworkFeeCode is returned if transaction has incorrect (too small per Policy setting)
    95  	// network fee value.
    96  	ErrInsufficientNetworkFeeCode = -504
    97  	// ErrPolicyFailedCode is returned from a call denied by the Policy contract (one of signers is blocked) or
    98  	// if one of the Policy filters failed.
    99  	ErrPolicyFailedCode = -505
   100  	// ErrInvalidScriptCode is returned if transaction contains incorrect executable script.
   101  	ErrInvalidScriptCode = -506
   102  	// ErrInvalidAttributeCode is returned if transaction contains an invalid attribute.
   103  	ErrInvalidAttributeCode = -507
   104  	// ErrInvalidSignatureCode is returned if one of the verification scripts failed.
   105  	ErrInvalidSignatureCode = -508
   106  	// ErrInvalidSizeCode is returned if transaction or its script is too big.
   107  	ErrInvalidSizeCode = -509
   108  	// ErrExpiredTransactionCode is returned if transaction's ValidUntilBlock value is already in the past.
   109  	ErrExpiredTransactionCode = -510
   110  	// ErrInsufficientFundsCode is returned if sender doesn't have enough GAS to pay for all currently pooled transactions.
   111  	ErrInsufficientFundsCode = -511
   112  	// ErrInvalidVerificationFunctionCode is returned if contract doesn't have a verify method or
   113  	// this method doesn't return proper value.
   114  	ErrInvalidVerificationFunctionCode = -512
   115  )
   116  
   117  // Errors related to node configuration and various services.
   118  const (
   119  	// ErrSessionsDisabledCode is returned if iterator session support is not enabled on the server.
   120  	ErrSessionsDisabledCode = -601
   121  	// ErrOracleDisabledCode is returned if Oracle service is not enabled in the configuration (service is not running).
   122  	ErrOracleDisabledCode = -602
   123  	// ErrOracleRequestFinishedCode is returned if Oracle request submitted is already completely processed.
   124  	// Can be returned only by the C# RPC server.
   125  	ErrOracleRequestFinishedCode = -603
   126  	// ErrOracleRequestNotFoundCode is returned if Oracle request submitted is not known to this node.
   127  	// Can be returned only by the C# RPC server.
   128  	ErrOracleRequestNotFoundCode = -604
   129  	// ErrOracleNotDesignatedNodeCode is returned if Oracle service is enabled, but this node is not designated
   130  	// to provide this functionality. Can be returned only by the C# RPC server.
   131  	ErrOracleNotDesignatedNodeCode = -605
   132  	// ErrUnsupportedStateCode is returned if this node can't answer requests for old state because it's configured
   133  	// to keep only the latest one.
   134  	ErrUnsupportedStateCode = -606
   135  	// ErrInvalidProofCode is returned if state proof verification failed.
   136  	ErrInvalidProofCode = -607
   137  	// ErrExecutionFailedCode is returned from a call made a VM execution, but it has failed.
   138  	ErrExecutionFailedCode = -608
   139  )
   140  
   141  var (
   142  	// ErrCompatGeneric is an error returned by nodes not compliant with the neo-project/proposals#156
   143  	// (NeoGo pre-0.102.0 and all known C# versions).
   144  	// It can be returned for any call and doesn't have any specific meaning.
   145  	//
   146  	// Deprecated: to be removed after all nodes adopt new error standard.
   147  	ErrCompatGeneric = NewErrorWithCode(-100, "RPC error")
   148  
   149  	// ErrCompatNoOpenedWallet is an error code returned by nodes not compliant with the neo-project/proposals#156
   150  	// (all known C# versions, NeoGo never used this code). It can be returned for wallet-related operations.
   151  	//
   152  	// Deprecated: to be removed after all nodes adopt new error standard.
   153  	ErrCompatNoOpenedWallet = NewErrorWithCode(-400, "No opened wallet")
   154  )
   155  
   156  var (
   157  	// ErrInvalidParams represents a generic "Invalid params" error.
   158  	ErrInvalidParams = NewInvalidParamsError("Invalid params")
   159  
   160  	// ErrUnknownBlock represents an error with code [ErrUnknownBlockCode].
   161  	// Call that accepts as a parameter or searches for a header or a block as a part of its job can't find it.
   162  	ErrUnknownBlock = NewErrorWithCode(ErrUnknownBlockCode, "Unknown block")
   163  	// ErrUnknownContract represents an error with code [ErrUnknownContractCode].
   164  	// Call that accepts as a parameter or searches for a contract as a part of its job can't find it.
   165  	ErrUnknownContract = NewErrorWithCode(ErrUnknownContractCode, "Unknown contract")
   166  	// ErrUnknownTransaction represents an error with code [ErrUnknownTransactionCode].
   167  	// Call that accepts as a parameter or searches for a transaction as a part of its job can't find it.
   168  	ErrUnknownTransaction = NewErrorWithCode(ErrUnknownTransactionCode, "Unknown transaction")
   169  	// ErrUnknownStorageItem represents an error with code [ErrUnknownStorageItemCode].
   170  	// Call that looks for an item in the contract storage as part of its job can't find it.
   171  	ErrUnknownStorageItem = NewErrorWithCode(ErrUnknownStorageItemCode, "Unknown storage item")
   172  	// ErrUnknownScriptContainer represents an error with code [ErrUnknownScriptContainerCode].
   173  	// Call that accepts as a parameter or searches for a script container (a block or transaction)
   174  	// as a part of its job can't find it (this error generalizes [ErrUnknownBlockCode] and [ErrUnknownTransactionCode]
   175  	// in cases where it's needed).
   176  	ErrUnknownScriptContainer = NewErrorWithCode(ErrUnknownScriptContainerCode, "Unknown script container")
   177  	// ErrUnknownStateRoot represents an error with code [ErrUnknownStateRootCode].
   178  	// Call that accepts as a parameter or searches for a state root as a part of its job can't find it.
   179  	ErrUnknownStateRoot = NewErrorWithCode(ErrUnknownStateRootCode, "Unknown state root")
   180  	// ErrUnknownSession represents an error with code [ErrUnknownSessionCode].
   181  	// Call that accepts as a parameter or searches for an iterator session as a part of its job can't find it.
   182  	ErrUnknownSession = NewErrorWithCode(ErrUnknownSessionCode, "Unknown session")
   183  	// ErrUnknownIterator represents an error with code [ErrUnknownIteratorCode].
   184  	// Call that accepts as a parameter or searches for a session iterator as a part of its job can't find it.
   185  	ErrUnknownIterator = NewErrorWithCode(ErrUnknownIteratorCode, "Unknown iterator")
   186  	// ErrUnknownHeight represents an error with code [ErrUnknownHeightCode].
   187  	// Block or header height passed as parameter or calculated during call execution is not correct
   188  	// (out of the range known to the node).
   189  	ErrUnknownHeight = NewErrorWithCode(ErrUnknownHeightCode, "Unknown height")
   190  
   191  	// ErrInsufficientFundsWallet represents an error with code [ErrInsufficientFundsWalletCode]. Can be returned only by the C# RPC server.
   192  	// Transaction that sends some assets can't be created because it fails.
   193  	ErrInsufficientFundsWallet = NewErrorWithCode(ErrInsufficientFundsWalletCode, "Insufficient funds")
   194  	// ErrWalletFeeLimit represents an error with code [ErrWalletFeeLimitCode]. Can be returned only by the C# RPC server.
   195  	// Transaction requires more network fee to be paid than is allowed by settings.
   196  	ErrWalletFeeLimit = NewErrorWithCode(ErrWalletFeeLimitCode, "Fee limit exceeded")
   197  	// ErrNoOpenedWallet represents an error with code [ErrNoOpenedWalletCode]. Can be returned only by the C# RPC server.
   198  	// Server doesn't have any opened wallet to operate with.
   199  	ErrNoOpenedWallet = NewErrorWithCode(ErrNoOpenedWalletCode, "No opened wallet")
   200  	// ErrWalletNotFound represents an error with code [ErrWalletNotFoundCode]. Can be returned only by the C# RPC server.
   201  	// Specified (or configured) wallet file path is invalid.
   202  	ErrWalletNotFound = NewErrorWithCode(ErrWalletNotFoundCode, "Wallet not found")
   203  	// ErrWalletNotSupported represents an error with code [ErrWalletNotSupportedCode]. Can be returned only by the C# RPC server.
   204  	// Specified (or configured) file can't be opened as a wallet.
   205  	ErrWalletNotSupported = NewErrorWithCode(ErrWalletNotSupportedCode, "Wallet not supported")
   206  
   207  	// ErrVerificationFailed represents an error with code [ErrVerificationFailedCode].
   208  	// Any verification error that can't be expressed by other codes.
   209  	ErrVerificationFailed = NewErrorWithCode(ErrVerificationFailedCode, "Unclassified inventory verification error")
   210  	// ErrAlreadyExists represents an error with code [ErrAlreadyExistsCode].
   211  	// Block or transaction is already accepted and processed on chain.
   212  	ErrAlreadyExists = NewErrorWithCode(ErrAlreadyExistsCode, "Inventory already exists on chain")
   213  	// ErrMempoolCapReached represents an error with code [ErrMempoolCapReachedCode].
   214  	// No more transactions can be accepted into the memory pool (unless they have a priority) as its full capacity is reached.
   215  	ErrMempoolCapReached = NewErrorWithCode(ErrMempoolCapReachedCode, "The memory pool is full and no more transactions can be sent")
   216  	// ErrAlreadyInPool represents an error with code [ErrAlreadyInPoolCode].
   217  	// Transaction is already pooled, but not yet accepted into a block.
   218  	ErrAlreadyInPool = NewErrorWithCode(ErrAlreadyInPoolCode, "Transaction already exists in the memory pool")
   219  	// ErrInsufficientNetworkFee represents an error with code [ErrInsufficientNetworkFeeCode].
   220  	// Transaction has incorrect (too small per Policy setting) network fee value.
   221  	ErrInsufficientNetworkFee = NewErrorWithCode(ErrInsufficientNetworkFeeCode, "Insufficient network fee")
   222  	// ErrPolicyFailed represents an error with code [ErrPolicyFailedCode].
   223  	// Denied by the Policy contract (one of signers is blocked).
   224  	ErrPolicyFailed = NewErrorWithCode(ErrPolicyFailedCode, "One of the Policy filters failed")
   225  	// ErrInvalidScript represents an error with code [ErrInvalidScriptCode].
   226  	// Transaction contains incorrect executable script.
   227  	ErrInvalidScript = NewErrorWithCode(ErrInvalidScriptCode, "Invalid script")
   228  	// ErrInvalidAttribute represents an error with code [ErrInvalidAttributeCode].
   229  	// Transaction contains an invalid attribute.
   230  	ErrInvalidAttribute = NewErrorWithCode(ErrInvalidAttributeCode, "Invalid transaction attribute")
   231  	// ErrInvalidSignature represents an error with code [ErrInvalidSignatureCode].
   232  	// One of the verification scripts failed.
   233  	ErrInvalidSignature = NewErrorWithCode(ErrInvalidSignatureCode, "Invalid signature")
   234  	// ErrInvalidSize represents an error with code [ErrInvalidSizeCode].
   235  	// Transaction or its script is too big.
   236  	ErrInvalidSize = NewErrorWithCode(ErrInvalidSizeCode, "Invalid inventory size")
   237  	// ErrExpiredTransaction represents an error with code [ErrExpiredTransactionCode].
   238  	// Transaction's ValidUntilBlock value is already in the past.
   239  	ErrExpiredTransaction = NewErrorWithCode(ErrExpiredTransactionCode, "Expired transaction")
   240  	// ErrInsufficientFunds represents an error with code [ErrInsufficientFundsCode].
   241  	// Sender doesn't have enough GAS to pay for all currently pooled transactions.
   242  	ErrInsufficientFunds = NewErrorWithCode(ErrInsufficientFundsCode, "Insufficient funds")
   243  	// ErrInvalidVerificationFunction represents an error with code [ErrInvalidVerificationFunctionCode].
   244  	// Contract doesn't have a verify method or this method doesn't return proper value.
   245  	ErrInvalidVerificationFunction = NewErrorWithCode(ErrInvalidVerificationFunctionCode, "Invalid verification function")
   246  
   247  	// ErrSessionsDisabled represents an error with code [ErrSessionsDisabledCode].
   248  	// Iterator session support is not enabled on the server.
   249  	ErrSessionsDisabled = NewErrorWithCode(ErrSessionsDisabledCode, "Sessions disabled")
   250  	// ErrOracleDisabled represents an error with code [ErrOracleDisabledCode].
   251  	// Service is not enabled in the configuration.
   252  	ErrOracleDisabled = NewErrorWithCode(ErrOracleDisabledCode, "Oracle service is not running")
   253  	// ErrOracleRequestFinished represents an error with code [ErrOracleRequestFinishedCode]. Can be returned only by the C# RPC server.
   254  	// The oracle request submitted is already completely processed.
   255  	ErrOracleRequestFinished = NewErrorWithCode(ErrOracleRequestFinishedCode, "Oracle request has already been finished")
   256  	// ErrOracleRequestNotFound represents an error with code [ErrOracleRequestNotFoundCode]. Can be returned only by the C# RPC server.
   257  	// The oracle request submitted is not known to this node.
   258  	ErrOracleRequestNotFound = NewErrorWithCode(ErrOracleRequestNotFoundCode, "Oracle request is not found")
   259  	// ErrOracleNotDesignatedNode represents an error with code [ErrOracleNotDesignatedNodeCode]. Can be returned only by the C# RPC server.
   260  	// Oracle service is enabled, but this node is not designated to provide this functionality.
   261  	ErrOracleNotDesignatedNode = NewErrorWithCode(ErrOracleNotDesignatedNodeCode, "Not a designated oracle node")
   262  	// ErrUnsupportedState represents an error with code [ErrUnsupportedStateCode].
   263  	// This node can't answer requests for old state because it's configured to keep only the latest one.
   264  	ErrUnsupportedState = NewErrorWithCode(ErrUnsupportedStateCode, "Old state requests are not supported")
   265  	// ErrInvalidProof represents an error with code [ErrInvalidProofCode].
   266  	// State proof verification failed.
   267  	ErrInvalidProof = NewErrorWithCode(ErrInvalidProofCode, "Invalid proof")
   268  	// ErrExecutionFailed represents an error with code [ErrExecutionFailedCode].
   269  	// Call made a VM execution, but it has failed.
   270  	ErrExecutionFailed = NewErrorWithCode(ErrExecutionFailedCode, "Execution failed")
   271  )
   272  
   273  // NewError is an Error constructor that takes Error contents from its parameters.
   274  func NewError(code int64, message string, data string) *Error {
   275  	return &Error{
   276  		Code:    code,
   277  		Message: message,
   278  		Data:    data,
   279  	}
   280  }
   281  
   282  // NewParseError creates a new error with code
   283  // -32700.
   284  func NewParseError(data string) *Error {
   285  	return NewError(BadRequestCode, "Parse error", data)
   286  }
   287  
   288  // NewInvalidRequestError creates a new error with
   289  // code -32600.
   290  func NewInvalidRequestError(data string) *Error {
   291  	return NewError(InvalidRequestCode, "Invalid request", data)
   292  }
   293  
   294  // NewMethodNotFoundError creates a new error with
   295  // code -32601.
   296  func NewMethodNotFoundError(data string) *Error {
   297  	return NewError(MethodNotFoundCode, "Method not found", data)
   298  }
   299  
   300  // NewInvalidParamsError creates a new error with
   301  // code -32602.
   302  func NewInvalidParamsError(data string) *Error {
   303  	return NewError(InvalidParamsCode, "Invalid params", data)
   304  }
   305  
   306  // NewInternalServerError creates a new error with
   307  // code -32603.
   308  func NewInternalServerError(data string) *Error {
   309  	return NewError(InternalServerErrorCode, "Internal error", data)
   310  }
   311  
   312  // NewErrorWithCode creates a new error with
   313  // specified error code and error message.
   314  func NewErrorWithCode(code int64, message string) *Error {
   315  	return NewError(code, message, "")
   316  }
   317  
   318  // WrapErrorWithData returns copy of the given error with the specified data and cause.
   319  // It does not modify the source error.
   320  func WrapErrorWithData(e *Error, data string) *Error {
   321  	return NewError(e.Code, e.Message, data)
   322  }
   323  
   324  // Error implements the error interface.
   325  func (e *Error) Error() string {
   326  	if len(e.Data) == 0 {
   327  		return fmt.Sprintf("%s (%d)", e.Message, e.Code)
   328  	}
   329  	return fmt.Sprintf("%s (%d) - %s", e.Message, e.Code, e.Data)
   330  }
   331  
   332  // Is denotes whether the error matches the target one.
   333  func (e *Error) Is(target error) bool {
   334  	var clTarget *Error
   335  	if errors.As(target, &clTarget) {
   336  		return e.Code == clTarget.Code
   337  	}
   338  	return false
   339  }