github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/rpc/web3/server.go (about) 1 // Code generated by go-openrpc. DO NOT EDIT. 2 package web3 3 4 import ( 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "reflect" 10 ) 11 12 const JSONRPC = "2.0" 13 14 type Code uint32 15 16 const ( 17 ErrUnknown Code = iota 18 ErrCouldNotParse 19 ErrInvalidRequest 20 ErrNotFound 21 ErrInvalidParams 22 ErrInternal 23 ErrServer 24 ) 25 26 func (c Code) Error() string { 27 return fmt.Sprintf("Error %d: %s", c, c.String()) 28 } 29 30 func (c Code) String() string { 31 switch c { 32 case ErrCouldNotParse: 33 return "could not parse input" 34 case ErrInvalidRequest: 35 return "invalid request" 36 case ErrNotFound: 37 return "not found" 38 case ErrInvalidParams: 39 return "invalid parameters" 40 case ErrInternal: 41 return "internal error" 42 case ErrServer: 43 return "server error" 44 default: 45 return "unknown error" 46 } 47 } 48 49 func (c Code) RPCError() *RPCError { 50 switch c { 51 case ErrCouldNotParse: 52 return NewRPCError(-32700, c.String()) 53 case ErrInvalidRequest: 54 return NewRPCError(-32600, c.String()) 55 case ErrNotFound: 56 return NewRPCError(-32601, c.String()) 57 case ErrInvalidParams: 58 return NewRPCError(-32602, c.String()) 59 case ErrInternal: 60 return NewRPCError(-32603, c.String()) 61 case ErrServer: 62 return NewRPCError(-32000, c.String()) 63 default: 64 return NewRPCError(-32099, c.String()) 65 } 66 } 67 68 func (c Code) RPCErrorWithMessage(msg string) *RPCError { 69 resp := c.RPCError() 70 resp.Message = msg 71 return resp 72 } 73 74 // https://www.jsonrpc.org/specification#request_object 75 type RPCRequest struct { 76 JSONRPC string `json:"jsonrpc"` 77 ID interface{} `json:"id"` 78 Method string `json:"method"` 79 Params json.RawMessage `json:"params"` 80 } 81 82 // https://www.jsonrpc.org/specification#response_object 83 type RPCResultResponse struct { 84 JSONRPC string `json:"jsonrpc"` 85 ID interface{} `json:"id"` 86 Result interface{} `json:"result"` 87 } 88 89 // https://www.jsonrpc.org/specification#response_object 90 type RPCErrorResponse struct { 91 JSONRPC string `json:"jsonrpc"` 92 ID interface{} `json:"id"` 93 Error *RPCError `json:"error"` 94 } 95 96 // https://www.jsonrpc.org/specification#error_object 97 type RPCError struct { 98 Code int `json:"code"` 99 Message string `json:"message"` 100 Data interface{} `json:"data,omitempty"` 101 } 102 103 func NewRPCError(code int, msg string) *RPCError { 104 return &RPCError{Code: code, Message: msg} 105 } 106 107 func (r *RPCError) AsRPCErrorResponse(id interface{}) RPCErrorResponse { 108 return RPCErrorResponse{ 109 JSONRPC: JSONRPC, 110 ID: id, 111 Error: r, 112 } 113 } 114 115 type Server struct { 116 service Service 117 } 118 119 func NewServer(rpc Service) *Server { 120 return &Server{rpc} 121 } 122 123 func (srv *Server) HandleHTTP(rpcPath string) { 124 http.Handle(rpcPath, srv) 125 } 126 127 // https://github.com/a8m/reflect-examples#wrap-a-reflectvalue-with-pointer-t--t 128 func ptr(v reflect.Value) reflect.Value { 129 pt := reflect.PtrTo(v.Type()) 130 pv := reflect.New(pt.Elem()) 131 pv.Elem().Set(v) 132 return pv 133 } 134 135 func ParamsToStruct(msg json.RawMessage, req interface{}) error { 136 // by-name 137 err := json.Unmarshal(msg, req) 138 if err == nil { 139 return nil 140 } 141 142 // by-position 143 params := make([]json.RawMessage, 0) 144 err = json.Unmarshal(msg, ¶ms) 145 if err != nil { 146 return err 147 } 148 val := reflect.ValueOf(req) 149 if val.Kind() == reflect.Ptr { 150 val = val.Elem() 151 } 152 153 for i, p := range params { 154 if i >= val.NumField() { 155 break 156 } 157 field := val.Field(i) 158 if field.CanSet() { 159 pf := ptr(field) 160 err = json.Unmarshal(p, pf.Interface()) 161 if err != nil { 162 return err 163 } 164 field.Set(pf.Elem()) 165 } 166 } 167 return nil 168 } 169 170 func StructToResult(in interface{}) interface{} { 171 val := reflect.ValueOf(in) 172 if val.Kind() == reflect.Ptr { 173 val = val.Elem() 174 } 175 if val.Kind() != reflect.Struct { 176 return in 177 } 178 if val.NumField() == 1 { 179 return val.Field(0).Interface() 180 } else if val.NumField() > 1 { 181 result := make([]interface{}, 0) 182 for i := 0; i < val.NumField(); i++ { 183 field := val.Field(i) 184 if val.Kind() == reflect.Ptr { 185 field = field.Elem() 186 } 187 188 if field.Kind() == reflect.Slice { 189 for i := 0; i < field.Len(); i++ { 190 result = append(result, field.Index(i).Interface()) 191 } 192 } else if field.CanInterface() { 193 result = append(result, field.Interface()) 194 } 195 } 196 return result 197 } else { 198 return nil 199 } 200 } 201 202 func (srv *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { 203 if r.Method == http.MethodOptions { 204 w.Header().Set("Access-Control-Allow-Origin", "*") 205 w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS") 206 w.Header().Set("Access-Control-Allow-Headers", "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range") 207 w.Header().Set("Accept-Range", "bytes") 208 w.WriteHeader(http.StatusOK) 209 w.Write([]byte{}) 210 return 211 } else if r.Method != http.MethodPost { 212 WriteData(w, ErrInternal.RPCError().AsRPCErrorResponse(nil)) 213 return 214 } 215 216 data, err := ioutil.ReadAll(r.Body) 217 if err != nil { 218 WriteData(w, ErrInvalidRequest.RPCError().AsRPCErrorResponse(nil)) 219 return 220 } 221 r.Body.Close() 222 223 requests := make([]RPCRequest, 0) 224 err = json.Unmarshal(data, &requests) 225 if err != nil { 226 request := new(RPCRequest) 227 err = json.Unmarshal(data, request) 228 if err != nil { 229 WriteData(w, ErrCouldNotParse.RPCError().AsRPCErrorResponse(nil)) 230 return 231 } 232 requests = []RPCRequest{*request} 233 } 234 235 responses := make([]interface{}, 0) 236 for _, req := range requests { 237 responses = append(responses, srv.Do(req)) 238 } 239 240 if len(responses) == 1 { 241 WriteData(w, responses[0]) 242 } else { 243 WriteData(w, responses) 244 } 245 } 246 247 func (srv *Server) Do(in RPCRequest) interface{} { 248 if in.JSONRPC != JSONRPC || in.Method == "" || in.ID == nil { 249 return ErrInvalidParams.RPCError().AsRPCErrorResponse(nil) 250 } 251 252 var err error 253 var out interface{} 254 255 switch in.Method { 256 case "web3_clientVersion": 257 out, err = srv.service.Web3ClientVersion() 258 case "web3_sha3": 259 req := new(Web3Sha3Params) 260 err = ParamsToStruct(in.Params, req) 261 if err == nil { 262 out, err = srv.service.Web3Sha3(req) 263 } 264 case "net_listening": 265 out, err = srv.service.NetListening() 266 case "net_peerCount": 267 out, err = srv.service.NetPeerCount() 268 case "net_version": 269 out, err = srv.service.NetVersion() 270 case "eth_blockNumber": 271 out, err = srv.service.EthBlockNumber() 272 case "eth_call": 273 req := new(EthCallParams) 274 err = ParamsToStruct(in.Params, req) 275 if err == nil { 276 out, err = srv.service.EthCall(req) 277 } 278 case "eth_chainId": 279 out, err = srv.service.EthChainId() 280 case "eth_coinbase": 281 out, err = srv.service.EthCoinbase() 282 case "eth_estimateGas": 283 req := new(EthEstimateGasParams) 284 err = ParamsToStruct(in.Params, req) 285 if err == nil { 286 out, err = srv.service.EthEstimateGas(req) 287 } 288 case "eth_gasPrice": 289 out, err = srv.service.EthGasPrice() 290 case "eth_getBalance": 291 req := new(EthGetBalanceParams) 292 err = ParamsToStruct(in.Params, req) 293 if err == nil { 294 out, err = srv.service.EthGetBalance(req) 295 } 296 case "eth_getBlockByHash": 297 req := new(EthGetBlockByHashParams) 298 err = ParamsToStruct(in.Params, req) 299 if err == nil { 300 out, err = srv.service.EthGetBlockByHash(req) 301 } 302 case "eth_getBlockByNumber": 303 req := new(EthGetBlockByNumberParams) 304 err = ParamsToStruct(in.Params, req) 305 if err == nil { 306 out, err = srv.service.EthGetBlockByNumber(req) 307 } 308 case "eth_getBlockTransactionCountByHash": 309 req := new(EthGetBlockTransactionCountByHashParams) 310 err = ParamsToStruct(in.Params, req) 311 if err == nil { 312 out, err = srv.service.EthGetBlockTransactionCountByHash(req) 313 } 314 case "eth_getBlockTransactionCountByNumber": 315 req := new(EthGetBlockTransactionCountByNumberParams) 316 err = ParamsToStruct(in.Params, req) 317 if err == nil { 318 out, err = srv.service.EthGetBlockTransactionCountByNumber(req) 319 } 320 case "eth_getCode": 321 req := new(EthGetCodeParams) 322 err = ParamsToStruct(in.Params, req) 323 if err == nil { 324 out, err = srv.service.EthGetCode(req) 325 } 326 case "eth_getFilterChanges": 327 req := new(EthGetFilterChangesParams) 328 err = ParamsToStruct(in.Params, req) 329 if err == nil { 330 out, err = srv.service.EthGetFilterChanges(req) 331 } 332 case "eth_getFilterLogs": 333 req := new(EthGetFilterLogsParams) 334 err = ParamsToStruct(in.Params, req) 335 if err == nil { 336 out, err = srv.service.EthGetFilterLogs(req) 337 } 338 case "eth_getRawTransactionByHash": 339 req := new(EthGetRawTransactionByHashParams) 340 err = ParamsToStruct(in.Params, req) 341 if err == nil { 342 out, err = srv.service.EthGetRawTransactionByHash(req) 343 } 344 case "eth_getRawTransactionByBlockHashAndIndex": 345 req := new(EthGetRawTransactionByBlockHashAndIndexParams) 346 err = ParamsToStruct(in.Params, req) 347 if err == nil { 348 out, err = srv.service.EthGetRawTransactionByBlockHashAndIndex(req) 349 } 350 case "eth_getRawTransactionByBlockNumberAndIndex": 351 req := new(EthGetRawTransactionByBlockNumberAndIndexParams) 352 err = ParamsToStruct(in.Params, req) 353 if err == nil { 354 out, err = srv.service.EthGetRawTransactionByBlockNumberAndIndex(req) 355 } 356 case "eth_getLogs": 357 req := new(EthGetLogsParams) 358 err = ParamsToStruct(in.Params, req) 359 if err == nil { 360 out, err = srv.service.EthGetLogs(req) 361 } 362 case "eth_getStorageAt": 363 req := new(EthGetStorageAtParams) 364 err = ParamsToStruct(in.Params, req) 365 if err == nil { 366 out, err = srv.service.EthGetStorageAt(req) 367 } 368 case "eth_getTransactionByBlockHashAndIndex": 369 req := new(EthGetTransactionByBlockHashAndIndexParams) 370 err = ParamsToStruct(in.Params, req) 371 if err == nil { 372 out, err = srv.service.EthGetTransactionByBlockHashAndIndex(req) 373 } 374 case "eth_getTransactionByBlockNumberAndIndex": 375 req := new(EthGetTransactionByBlockNumberAndIndexParams) 376 err = ParamsToStruct(in.Params, req) 377 if err == nil { 378 out, err = srv.service.EthGetTransactionByBlockNumberAndIndex(req) 379 } 380 case "eth_getTransactionByHash": 381 req := new(EthGetTransactionByHashParams) 382 err = ParamsToStruct(in.Params, req) 383 if err == nil { 384 out, err = srv.service.EthGetTransactionByHash(req) 385 } 386 case "eth_getTransactionCount": 387 req := new(EthGetTransactionCountParams) 388 err = ParamsToStruct(in.Params, req) 389 if err == nil { 390 out, err = srv.service.EthGetTransactionCount(req) 391 } 392 case "eth_getTransactionReceipt": 393 req := new(EthGetTransactionReceiptParams) 394 err = ParamsToStruct(in.Params, req) 395 if err == nil { 396 out, err = srv.service.EthGetTransactionReceipt(req) 397 } 398 case "eth_getUncleByBlockHashAndIndex": 399 req := new(EthGetUncleByBlockHashAndIndexParams) 400 err = ParamsToStruct(in.Params, req) 401 if err == nil { 402 out, err = srv.service.EthGetUncleByBlockHashAndIndex(req) 403 } 404 case "eth_getUncleByBlockNumberAndIndex": 405 req := new(EthGetUncleByBlockNumberAndIndexParams) 406 err = ParamsToStruct(in.Params, req) 407 if err == nil { 408 out, err = srv.service.EthGetUncleByBlockNumberAndIndex(req) 409 } 410 case "eth_getUncleCountByBlockHash": 411 req := new(EthGetUncleCountByBlockHashParams) 412 err = ParamsToStruct(in.Params, req) 413 if err == nil { 414 out, err = srv.service.EthGetUncleCountByBlockHash(req) 415 } 416 case "eth_getUncleCountByBlockNumber": 417 req := new(EthGetUncleCountByBlockNumberParams) 418 err = ParamsToStruct(in.Params, req) 419 if err == nil { 420 out, err = srv.service.EthGetUncleCountByBlockNumber(req) 421 } 422 case "eth_getProof": 423 req := new(EthGetProofParams) 424 err = ParamsToStruct(in.Params, req) 425 if err == nil { 426 out, err = srv.service.EthGetProof(req) 427 } 428 case "eth_getWork": 429 out, err = srv.service.EthGetWork() 430 case "eth_hashrate": 431 out, err = srv.service.EthHashrate() 432 case "eth_mining": 433 out, err = srv.service.EthMining() 434 case "eth_newBlockFilter": 435 out, err = srv.service.EthNewBlockFilter() 436 case "eth_newFilter": 437 req := new(EthNewFilterParams) 438 err = ParamsToStruct(in.Params, req) 439 if err == nil { 440 out, err = srv.service.EthNewFilter(req) 441 } 442 case "eth_newPendingTransactionFilter": 443 out, err = srv.service.EthNewPendingTransactionFilter() 444 case "eth_pendingTransactions": 445 out, err = srv.service.EthPendingTransactions() 446 case "eth_protocolVersion": 447 out, err = srv.service.EthProtocolVersion() 448 case "eth_sign": 449 req := new(EthSignParams) 450 err = ParamsToStruct(in.Params, req) 451 if err == nil { 452 out, err = srv.service.EthSign(req) 453 } 454 case "eth_accounts": 455 out, err = srv.service.EthAccounts() 456 case "eth_sendTransaction": 457 req := new(EthSendTransactionParams) 458 err = ParamsToStruct(in.Params, req) 459 if err == nil { 460 out, err = srv.service.EthSendTransaction(req) 461 } 462 case "eth_sendRawTransaction": 463 req := new(EthSendRawTransactionParams) 464 err = ParamsToStruct(in.Params, req) 465 if err == nil { 466 out, err = srv.service.EthSendRawTransaction(req) 467 } 468 case "eth_submitHashrate": 469 req := new(EthSubmitHashrateParams) 470 err = ParamsToStruct(in.Params, req) 471 if err == nil { 472 out, err = srv.service.EthSubmitHashrate(req) 473 } 474 case "eth_submitWork": 475 req := new(EthSubmitWorkParams) 476 err = ParamsToStruct(in.Params, req) 477 if err == nil { 478 out, err = srv.service.EthSubmitWork(req) 479 } 480 case "eth_syncing": 481 out, err = srv.service.EthSyncing() 482 case "eth_uninstallFilter": 483 req := new(EthUninstallFilterParams) 484 err = ParamsToStruct(in.Params, req) 485 if err == nil { 486 out, err = srv.service.EthUninstallFilter(req) 487 } 488 } 489 490 if err != nil { 491 return ErrInternal.RPCErrorWithMessage(err.Error()).AsRPCErrorResponse(in.ID) 492 } 493 494 return RPCResultResponse{ 495 JSONRPC: JSONRPC, 496 ID: in.ID, 497 Result: StructToResult(out), 498 } 499 } 500 501 func WriteData(w http.ResponseWriter, resp interface{}) { 502 data, err := json.Marshal(resp) 503 if err != nil { 504 panic(err) 505 } 506 w.Header().Set("Content-Type", "application/json") 507 w.Write(data) 508 }