go-eth-proxy

Transparent proxy server for eth-cache
Info | Log | Files | Refs

commit 6b9489135e33edbea681f9ce5274848c5bffb5b7
parent aaf37609b603e33bc6b66980cc71f0614dab704d
Author: lash <dev@holbrook.no>
Date:   Tue,  9 Jul 2024 21:03:34 +0100

Enable use of numeric id in jsonrpc

Diffstat:
Mrpc/geth/service.go | 2+-
Mrpc/literal.go | 7+------
Mrpc/rpc.go | 48++++++++++++++++++++++++++++++++----------------
Mrpc/service.go | 39++++++++++++++++++++++++---------------
4 files changed, 58 insertions(+), 38 deletions(-)

diff --git a/rpc/geth/service.go b/rpc/geth/service.go @@ -31,6 +31,6 @@ func (p *ProxyService) GetTransactionByHash(ctx context.Context, hsh string) (*t if err != nil { return nil, err } - log.Printf("tx %s gasprice %u gas %u", tx.Type(), tx.GasPrice(), tx.Gas()) + log.Printf("tx %v gasprice %d gas %d", tx.Type(), tx.GasPrice(), tx.Gas()) return tx, nil } diff --git a/rpc/literal.go b/rpc/literal.go @@ -24,10 +24,6 @@ func inJson(b []byte) (*jsonRpcMsgFull, error) { return msg, err } -func outJson(msg *jsonRpcResponse) []byte { - return []byte{} -} - func (l *literalBackend) ServeHTTP(w http.ResponseWriter, r *http.Request) { var err error @@ -62,8 +58,7 @@ func (l *literalBackend) ServeHTTP(w http.ResponseWriter, r *http.Request) { } if err != nil { - s := fmt.Sprintf("Status: %d Not found", http.StatusNotFound) - w.Write([]byte(s)) + w.WriteHeader(http.StatusNotFound) return } diff --git a/rpc/rpc.go b/rpc/rpc.go @@ -4,10 +4,13 @@ package rpc import ( "bytes" "encoding/json" + "fmt" "io" "log" "net/http" "net/url" + "strconv" + "strings" ) type jsonRpcMsg struct { @@ -16,21 +19,23 @@ type jsonRpcMsg struct { type jsonRpcMsgFull struct { Method string - Id string + Id any Params []any } -type jsonRpcError struct { - Code int +type JsonRpcError struct { + Code int `json:"code"` + Message string `json:"message"` } -type jsonRpcResponse struct { - Error jsonRpcError +type JsonRpcResponse struct { + Id any `json:"id"` + Error JsonRpcError `json:"error"` } type jsonRpcResponseFull struct { Jsonrpc string `json:"jsonrpc"` - Id string `json:"id"` + Id any `json:"id"` Result any `json:"result"` } @@ -40,8 +45,8 @@ type ProxyServer struct { } type proxyWriter struct { + Status int header map[string][]string - status int data *bytes.Buffer afterHeader bool } @@ -57,8 +62,8 @@ func (p *proxyWriter) Write(b []byte) (int, error) { } func (p *proxyWriter) WriteHeader(status int) { - p.status = status - + p.Status = status + p.header["Status"] = []string{fmt.Sprintf("%d", status)} } func (p *proxyWriter) Copy(w http.ResponseWriter) (int, error) { @@ -134,18 +139,29 @@ func (s *ProxyServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { if msg.Method == k { log.Printf("proxy match method %s %s", k, msg.Method) s.Server.ServeHTTP(rw, r) - rsp := jsonRpcResponse{} - err = json.Unmarshal(b, &rsp) + hd := rw.Header() + parts := strings.SplitN(hd["Status"][0], " ", 1) + status, err := strconv.ParseInt(parts[0], 10, 16) if (err != nil) { - log.Printf("%s", err) r.Body.Close() w.WriteHeader(http.StatusInternalServerError) return } - if rsp.Error.Code == 0 { - rw.WriteHeader(http.StatusOK) - rw.Copy(w) - return + if status < 300 && status >= 200 { + rsp := JsonRpcResponse{ + Error: JsonRpcError{}, + } + err = json.Unmarshal(b, &rsp) + if (err != nil) { + r.Body.Close() + w.WriteHeader(http.StatusInternalServerError) + return + } + if rsp.Error.Code == 0 { + rw.WriteHeader(http.StatusOK) + rw.Copy(w) + return + } } log.Printf("not found in proxy: %s", k) diff --git a/rpc/service.go b/rpc/service.go @@ -3,6 +3,7 @@ package rpc import ( "context" "fmt" + "log" "github.com/ethereum/go-ethereum/common" @@ -19,12 +20,23 @@ func NewProxyService(store store.Store) (*LiteralProxyService) { } } -func wrapResult(id string, result []byte) []byte { - s := fmt.Sprintf("{\"jsonrpc\":\"2.0\",\"id\":\"%s\",\"result\":%s}", id, result) - return []byte(s) +func wrapResult(id any, result []byte) ([]byte, error) { + var s string + var id_i int + id_s, ok := id.(string) + if ok { + s = fmt.Sprintf("{\"jsonrpc\":\"2.0\",\"id\":\"%s\",\"result\":%s}", id_s, result) + } else { + id_i, ok = id.(int) + if !ok { + return nil, fmt.Errorf("id not valid type") + } + s = fmt.Sprintf("{\"jsonrpc\":\"2.0\",\"id\":%d,\"result\":%s}", id_i, result) + } + return []byte(s), nil } -func (p *LiteralProxyService) GetTransactionByHash(ctx context.Context, id string, hsh string) ([]byte, error) { +func (p *LiteralProxyService) GetTransactionByHash(ctx context.Context, id any, hsh string) ([]byte, error) { var err error b := common.FromHex(hsh) @@ -33,11 +45,10 @@ func (p *LiteralProxyService) GetTransactionByHash(ctx context.Context, id strin return nil, err } - r := wrapResult(id, b) - return r, nil + return wrapResult(id, b) } -func (p *LiteralProxyService) GetTransactionReceipt(ctx context.Context, id string, hsh string) ([]byte, error) { +func (p *LiteralProxyService) GetTransactionReceipt(ctx context.Context, id any, hsh string) ([]byte, error) { var err error b := common.FromHex(hsh) @@ -46,11 +57,10 @@ func (p *LiteralProxyService) GetTransactionReceipt(ctx context.Context, id stri return nil, err } - r := wrapResult(id, b) - return r, nil + return wrapResult(id, b) } -func (p *LiteralProxyService) GetBlockByHash(ctx context.Context, id string, hsh string) ([]byte, error) { +func (p *LiteralProxyService) GetBlockByHash(ctx context.Context, id any, hsh string) ([]byte, error) { var err error b := common.FromHex(hsh) @@ -59,17 +69,16 @@ func (p *LiteralProxyService) GetBlockByHash(ctx context.Context, id string, hsh return nil, err } - r := wrapResult(id, b) - return r, nil + return wrapResult(id, b) } -func (p *LiteralProxyService) GetBlockByNumber(ctx context.Context, id string, numhex string) ([]byte, error) { +func (p *LiteralProxyService) GetBlockByNumber(ctx context.Context, id any, numhex string) ([]byte, error) { b := common.FromHex(numhex) b, err := p.store.GetBlockNumber(b) + log.Printf("result %v", b) if err != nil { return nil, err } - r := wrapResult(id, b) - return r, nil + return wrapResult(id, b) }