|
| 1 | +<pre> |
| 2 | + NEP: 23 |
| 3 | + Title: Neo JSON-RPC error handling and codes |
| 4 | + Author: Anna Shaleva < [email protected]>, Roman Khimov < [email protected]> |
| 5 | + Type: Informational |
| 6 | + Status: Final |
| 7 | + Created: 2022-09-12 |
| 8 | +</pre> |
| 9 | + |
| 10 | +==Abstract== |
| 11 | + |
| 12 | +This proposal describes some Neo-specific JSON-RPC interaction requirements |
| 13 | +along with a set of Neo-specific error codes to be used by compliant |
| 14 | +implementations. It allows different Neo nodes with different RPC server |
| 15 | +implementations to be compatible and able to interact with various RPC |
| 16 | +clients. |
| 17 | + |
| 18 | +==Motivation== |
| 19 | + |
| 20 | +Currently different implementations of RPC servers in Neo nodes use slightly |
| 21 | +different set of error codes and clients can't rely on codes to distinguish |
| 22 | +one error from another. Some errors were also changed on update from Legacy |
| 23 | +to N3. The overall set is also too coarse to be used effectively by clients, |
| 24 | +many different problems requiring different client actions end up with the |
| 25 | +same code, so clients have to parse error messages to react correctly which is |
| 26 | +far less reliable than using codes. At the same time JSON-RPC is too |
| 27 | +permissive in some of its definitions, while Neo can benefit from stricter |
| 28 | +definitions used. |
| 29 | + |
| 30 | +A standard set of errors and JSON-RPC conventions solve these problems by |
| 31 | +providing common language both for servers and clients. Servers can have a |
| 32 | +reference on what code should be used for what purpose and what data types |
| 33 | +should be used, while clients can easily check for error codes and react |
| 34 | +accordingly. |
| 35 | + |
| 36 | +==Specification== |
| 37 | + |
| 38 | +===General JSON-RPC conventions=== |
| 39 | + |
| 40 | +JSON-RPC 2.0 specification for the <code>Error</code> object is augmented with |
| 41 | +the following compatible clauses: |
| 42 | + |
| 43 | +* <code>code</code> field MUST be a negative integer value ranging from -1 to -65536 that is reserved for a particular error by the specification. <code>code</code> field MUST be the same for each Neo node irrespective of the implementation details except for the reserved experimental implementation-defined range. <code>code</code> field MUST NOT be omitted. |
| 44 | +* <code>message</code> field MUST be a valid UTF-8 string value that specifies a short error description. <code>message</code> value MAY NOT be exactly the same across all Neo node implementations (we have <code>code</code> for this). <code>message</code> value SHOULD be limited to a concise single sentence. <code>message</code> field MUST NOT be omitted. <code>message</code> field SHOULD start with a capital letter and SHOULD NOT end with a dot. |
| 45 | +* <code>data</code> field MUST be a valid UTF-8 string value that contains any implementation-dependent textual data (including debug traces). <code>data</code> field MAY be omitted, however it’s RECOMMENDED for servers to return it. <code>data</code> value SHOULD contain additional information about error and be aimed to clarify the error reason. <code>data</code> value MAY NOT be exactly the same across Neo node implementations. |
| 46 | +
|
| 47 | +===Error codes=== |
| 48 | + |
| 49 | +Compliant server implementations can use error codes defined by JSON-RPC |
| 50 | +specification (from -32700 to -32600) for any calls when they're |
| 51 | +appropriate. The most often used one is -32602 "Invalid params", it SHOULD be |
| 52 | +used only when call parameters are syntactically incorrect and servers |
| 53 | +SHOULD give additional data like offending parameter number and why it's wrong |
| 54 | +in the <code>data</code> response field. |
| 55 | + |
| 56 | +If several codes can be used in some situations implementations SHOULD pick |
| 57 | +the most specific one. |
| 58 | + |
| 59 | +====Groups==== |
| 60 | + |
| 61 | +Error codes are grouped. Each call can use any appropriate group and code as |
| 62 | +long as they fit the purpose. |
| 63 | + |
| 64 | +{| |
| 65 | +|+ Error code ranges |
| 66 | +|- |
| 67 | +! Range !! Usage |
| 68 | +|- |
| 69 | +| -15000...-10000 || Experimental implementation-defined range. |
| 70 | +|- |
| 71 | +| -699...-600 || Configuration and service errors. |
| 72 | +|- |
| 73 | +| -599...-500 || Inventory verification errors. |
| 74 | +|- |
| 75 | +| -399...-300 || Wallet-related errors. |
| 76 | +|- |
| 77 | +| -199...-100 || Missing/unknown items/inventories/states. |
| 78 | +|} |
| 79 | + |
| 80 | +Experimental codes can be used by node implementations if they're documented, |
| 81 | +however clients can't rely on the meaning of these codes if the version of the |
| 82 | +node changes or if they connect to a different node implementation. New |
| 83 | +proposals can set new ranges or specific codes as long as they don't conflict |
| 84 | +with this specification. All the remaining error codes (not listed in this |
| 85 | +specification or JSON-RPC 2.0) are reserved for future use and MUST NOT be |
| 86 | +used by compliant implementations. |
| 87 | + |
| 88 | +====Missing items==== |
| 89 | + |
| 90 | +{| |
| 91 | +|+ Codes for missing items |
| 92 | +|- |
| 93 | +! Code !! Message !! Meaning |
| 94 | +|- |
| 95 | +| -101 || Unknown block || Call that accepts as a parameter or searches for a header or a block as a part of its job can't find it. |
| 96 | +|- |
| 97 | +| -102 || Unknown contract || Call that accepts as a parameter or searches for a contract as a part of its job can't find it. |
| 98 | +|- |
| 99 | +| -103 || Unknown transaction|| Call that accepts as a parameter or searches for a transaction as a part of its job can't find it. |
| 100 | +|- |
| 101 | +| -104 || Unknown storage item|| Call that looks for an item in the storage as part of its job can't find it. |
| 102 | +|- |
| 103 | +| -105 || Unknown script container|| Call that accepts as a parameter or searches for a script container (a block or transaction) as a part of its job can't find it (this error generalizes -101 and -103 in cases where it's needed). |
| 104 | +|- |
| 105 | +| -106 || Unknown state root || Call that accepts as a parameter or searches for a state root as a part of its job can't find it. |
| 106 | +|- |
| 107 | +| -107 || Unknown session || Call that accepts as a parameter or searches for a session as a part of its job can't find it. |
| 108 | +|- |
| 109 | +| -108 || Unknown iterator || Call that accepts as a parameter or searches for a session iterator as a part of its job can't find it. |
| 110 | +|- |
| 111 | +| -109 || Unknown height || Block or header height passed as parameter or calculated during call execution is not correct (out of the range known to the node). |
| 112 | +|} |
| 113 | + |
| 114 | + |
| 115 | +====Wallet-related problems==== |
| 116 | + |
| 117 | +{| |
| 118 | +|+ Codes for calls that use a wallet |
| 119 | +|- |
| 120 | +! Code !! Message !! Meaning |
| 121 | +|- |
| 122 | +| -300 || Insufficient funds || Transaction that sends some assets can't be created because it fails. |
| 123 | +|- |
| 124 | +| -301 || Fee limit exceeded || Transaction requires more network fee to be paid than is allowed by settings. |
| 125 | +|- |
| 126 | +| -302 || No opened wallet || Server doesn't have any opened wallet to operate with. |
| 127 | +|- |
| 128 | +| -303 || Wallet not found || Specified (or configured) wallet file path is invalid. |
| 129 | +|- |
| 130 | +| -304 || Wallet not supported|| Specified (or configured) file can't be opened as a wallet. |
| 131 | +|} |
| 132 | + |
| 133 | +====Verification errors==== |
| 134 | + |
| 135 | +{| |
| 136 | +|+ Inventory verification or verification script errors |
| 137 | +|- |
| 138 | +! Code !! Message !! Meaning |
| 139 | +|- |
| 140 | +| -500 || Unclassified verification error|| Anything that can't be expressed by other codes. |
| 141 | +|- |
| 142 | +| -501 || Inventory already exists on chain|| Block or transaction is already accepted and processed. |
| 143 | +|- |
| 144 | +| -502 || Memory pool is full|| No more transactions can be accepted into the memory pool (unless they have a priority) as its full capacity is reached. |
| 145 | +|- |
| 146 | +| -503 || Transaction already exists in the pool|| Transaction is already pooled, but not yet accepted into a block. |
| 147 | +|- |
| 148 | +| -504 || Insufficient network fee|| Transaction has incorrect (too small per Policy setting) network fee value. |
| 149 | +|- |
| 150 | +| -505 || Policy check failed|| Denied by the Policy contract (one of signers is blocked). |
| 151 | +|- |
| 152 | +| -506 || Invalid script || Transaction contains incorrect executable script. |
| 153 | +|- |
| 154 | +| -507 || Invalid attribute || Transaction contains an invalid attribute. |
| 155 | +|- |
| 156 | +| -508 || Invalid signature || One of the verification scripts failed. |
| 157 | +|- |
| 158 | +| -509 || Invalid size || Transaction or its script is too big. |
| 159 | +|- |
| 160 | +| -510 || Expired || Transaction's ValidUntilBlock value is already in the past or NotValidBefore attribute value is in future. |
| 161 | +|- |
| 162 | +| -511 || Insufficient funds || Sender doesn't have enough GAS to pay for all currently pooled transactions. |
| 163 | +|- |
| 164 | +| -512 || Invalid verification function|| Contract doesn't have a <code>verify</code> method or this method doesn't return proper value. |
| 165 | +|- |
| 166 | +| -513 || Conflicts || There is a conflict with another transaction already in memory pool caused by one or both of them having a Conflicts attribute. |
| 167 | +|} |
| 168 | + |
| 169 | +====Service and node configuration==== |
| 170 | + |
| 171 | +{| |
| 172 | +|+ Errors related to node configuration and various services |
| 173 | +|- |
| 174 | +! Code !! Message !! Meaning |
| 175 | +|- |
| 176 | +| -600 || Access denied || Server requires authentication or has a policy not allowing request to be processed. |
| 177 | +|- |
| 178 | +| -601 || Sessions disabled || Session support is not enabled on the server. |
| 179 | +|- |
| 180 | +| -602 || Oracle service is not running|| Service is not enabled in the configuration. |
| 181 | +|- |
| 182 | +| -603 || Oracle request already finished|| The oracle request submitted is already completely processed. |
| 183 | +|- |
| 184 | +| -604 || Oracle request not found || The oracle request submitted is not known to this node. |
| 185 | +|- |
| 186 | +| -605 || Not a designated oracle node|| Oracle service is enabled, but this node is not designated to provide this functionality. |
| 187 | +|- |
| 188 | +| -606 || Old state requests are not supported|| This node can't answer requests for old state because it's configured to keep only the latest one. |
| 189 | +|- |
| 190 | +| -607 || Invalid proof || State proof verification failed. |
| 191 | +|- |
| 192 | +| -608 || Execution failed || Call made a VM execution, but it has failed. |
| 193 | +|} |
| 194 | + |
| 195 | +===Applicability to current calls=== |
| 196 | + |
| 197 | +This table is informative, compliant implementations MAY use other codes |
| 198 | +specified above that fit the purpose as well if they're documented. Only |
| 199 | +Neo-specific codes are documented here (except -600 that can be returned |
| 200 | +for any call), generic JSON-RPC errors like -32602 or |
| 201 | +-32603 can be used by any of these methods. |
| 202 | + |
| 203 | +{| |
| 204 | +|+ Error codes returned from specific calls |
| 205 | +|- |
| 206 | +! Method !! Codes |
| 207 | +|- |
| 208 | +| calculatenetworkfee || -508, -512 |
| 209 | +|- |
| 210 | +| closewallet || |
| 211 | +|- |
| 212 | +| dumpprivkey || -302 |
| 213 | +|- |
| 214 | +| findstates || -102, -606 |
| 215 | +|- |
| 216 | +| getapplicationlog || -105 |
| 217 | +|- |
| 218 | +| getblock || -101, -109 |
| 219 | +|- |
| 220 | +| getblockhash || -109 |
| 221 | +|- |
| 222 | +| getblockheader || -101, -109 |
| 223 | +|- |
| 224 | +| getcandidates || |
| 225 | +|- |
| 226 | +| getcommittee || |
| 227 | +|- |
| 228 | +| getconnectioncount || |
| 229 | +|- |
| 230 | +| getcontractstate || -102 |
| 231 | +|- |
| 232 | +| getnativecontracts || |
| 233 | +|- |
| 234 | +| getnep11balances || |
| 235 | +|- |
| 236 | +| getnep11properties || -608 |
| 237 | +|- |
| 238 | +| getnep11transfers || |
| 239 | +|- |
| 240 | +| getnep17balances || |
| 241 | +|- |
| 242 | +| getnep17transfers || |
| 243 | +|- |
| 244 | +| getnewaddress || -302 |
| 245 | +|- |
| 246 | +| getnextblockvalidators|| |
| 247 | +|- |
| 248 | +| getpeers || |
| 249 | +|- |
| 250 | +| getproof || -102, -104, -606 |
| 251 | +|- |
| 252 | +| getrawmempool || |
| 253 | +|- |
| 254 | +| getrawtransaction || -103 |
| 255 | +|- |
| 256 | +| getstate || -102, -606 |
| 257 | +|- |
| 258 | +| getstateheight || |
| 259 | +|- |
| 260 | +| getstateroot || -106 |
| 261 | +|- |
| 262 | +| getstorage || -102, -104 |
| 263 | +|- |
| 264 | +| gettransactionheight|| -103 |
| 265 | +|- |
| 266 | +| getunclaimedgas || |
| 267 | +|- |
| 268 | +| getversion || |
| 269 | +|- |
| 270 | +| getwalletbalance || -302 |
| 271 | +|- |
| 272 | +| getwalletunclaimedgas|| -302 |
| 273 | +|- |
| 274 | +| invokecontractverify|| -102, -512 |
| 275 | +|- |
| 276 | +| invokefunction || |
| 277 | +|- |
| 278 | +| invokescript || |
| 279 | +|- |
| 280 | +| importprivkey || -302 |
| 281 | +|- |
| 282 | +| listaddress || -302 |
| 283 | +|- |
| 284 | +| listplugins || |
| 285 | +|- |
| 286 | +| openwallet || -302, -303, -304 |
| 287 | +|- |
| 288 | +| sendfrom || -300, -301, -302 |
| 289 | +|- |
| 290 | +| sendmany || -300, -301, -302 |
| 291 | +|- |
| 292 | +| sendtoaddress || -300, -301, -302 |
| 293 | +|- |
| 294 | +| sendrawtransaction || -500, -501, -502, -503, -504, -505, -506, -507, -508, -509, -510, -511 |
| 295 | +|- |
| 296 | +| submitblock || -500, -501, -502, -503, -504, -505, -506, -507, -508, -509, -510, -511 |
| 297 | +|- |
| 298 | +| submitoracleresponse|| -508, -602, -603, -604, -605 |
| 299 | +|- |
| 300 | +| terminatesession || -107, -601 |
| 301 | +|- |
| 302 | +| traverseiterator || -107, -108, -601 |
| 303 | +|- |
| 304 | +| validateaddress || |
| 305 | +|- |
| 306 | +| verifyproof || -606, -607 |
| 307 | +|} |
| 308 | + |
| 309 | + |
| 310 | +==Rationale== |
| 311 | + |
| 312 | +A large set of codes and behavior nuances is directly inhereted from current |
| 313 | +implementations. New ones are added where clients need more details to |
| 314 | +properly interpret server response. The most important changes are in the |
| 315 | +verification group, specific errors allow clients to adjust the behavior |
| 316 | +accordingly: fail, retry or wait. |
| 317 | + |
| 318 | +==Backwards Compatibility== |
| 319 | + |
| 320 | +* -100 code is gone completely, it's returned for a very wide variety of different problems at the moment, so the code itself shouldn't matter much |
| 321 | +* -101 and -102 errors change their meaning, they're only used in <code>invokecontractverify</code> call which is not very popular |
| 322 | +* -300 and -301 wallet-related errors are completely compatible |
| 323 | +* -400 error is now -302 or -600 (depending on its meaning) which may affect some applications |
| 324 | +* -500 error has the same meaning and is compatible |
| 325 | +* new codes can affect client applications that expect only old ones |
| 326 | +
|
| 327 | +==References== |
| 328 | + |
| 329 | +* [https://www.jsonrpc.org/specification JSON-RPC 2.0 Specification] |
| 330 | +
|
| 331 | +==Implementation== |
| 332 | + |
| 333 | +* https://pkg.go.dev/github.com/nspcc-dev/[email protected]/pkg/neorpc#pkg-constants and server in https://github.com/nspcc-dev/neo-go/tree/v0.105.1/pkg/services/rpcsrv |
| 334 | +* https://github.com/neo-project/neo-modules/pull/815 |
0 commit comments