From e5f490cea1229ed1a0bcdf89dee96343f5cd8e31 Mon Sep 17 00:00:00 2001 From: Minh Doan Date: Fri, 12 Apr 2019 13:14:18 -0700 Subject: [PATCH] rpc investigation --- rpc/README.md | 20 ++++++++++++++++++++ rpc/client.go | 3 +++ rpc/handler.go | 3 +++ rpc/json.go | 2 ++ 4 files changed, 28 insertions(+) create mode 100644 rpc/README.md diff --git a/rpc/README.md b/rpc/README.md new file mode 100644 index 0000000000..060af214a4 --- /dev/null +++ b/rpc/README.md @@ -0,0 +1,20 @@ +# Walk-through of rpc package + +## rpc package + +If you go through every single files under rpc package you can see there is no import from other packages except logging or cors. This means rpc package is very modulalized and separated module from the rest in go-ethereum code base. We can incorporate easily by copying the whole directory. + +In high-level there are implmentation of client and server. + +### Client + +- To create a client, we call [newClient](https://github.com/daywednes/go-ethereum/blob/master/rpc/client.go#L194) + +## Links from other package to rpc + +- from [cmd/swarm/global-store](https://github.com/daywednes/go-ethereum/blob/bca140b73dc107676c912d87f6fe9c352d5fd0d8/cmd/swarm/global-store/global_store.go#L96) +- from [node/node.go:startRPC](https://github.com/daywednes/go-ethereum/blob/bca140b73dc107676c912d87f6fe9c352d5fd0d8/node/node.go#L281) which has calls [In-Process RPC endpoint](https://github.com/daywednes/go-ethereum/blob/bca140b73dc107676c912d87f6fe9c352d5fd0d8/node/node.go#L288), call to [IPC RPC endpoint](https://github.com/daywednes/go-ethereum/blob/bca140b73dc107676c912d87f6fe9c352d5fd0d8/node/node.go#L334), [HTTP RPC endpoint](https://github.com/daywednes/go-ethereum/blob/bca140b73dc107676c912d87f6fe9c352d5fd0d8/node/node.go#L363). startRPC is called from [node.Start](https://github.com/daywednes/go-ethereum/blob/bca140b73dc107676c912d87f6fe9c352d5fd0d8/node/node.go#L162) +- [node.Start](https://github.com/daywednes/go-ethereum/blob/bca140b73dc107676c912d87f6fe9c352d5fd0d8/node/node.go#L162) is called from + - [mobile/n.node.Start](https://github.com/daywednes/go-ethereum/blob/bca140b73dc107676c912d87f6fe9c352d5fd0d8/mobile/geth.go#L202) + - [cmd/faucet:stack.Start()](https://github.com/daywednes/go-ethereum/blob/bca140b73dc107676c912d87f6fe9c352d5fd0d8/cmd/faucet/faucet.go#L254) + - [cmd/utils/StartNode](https://github.com/daywednes/go-ethereum/blob/bca140b73dc107676c912d87f6fe9c352d5fd0d8/cmd/utils/cmd.go#L66) which is called from geth/main.go diff --git a/rpc/client.go b/rpc/client.go index 02029dc8f6..f6ed03511e 100644 --- a/rpc/client.go +++ b/rpc/client.go @@ -110,6 +110,7 @@ type clientConn struct { handler *handler } +// minhdoan: create a client connection with ServerCodec. func (c *Client) newClientConn(conn ServerCodec) *clientConn { ctx := context.WithValue(context.Background(), clientContextKey{}, c) handler := newHandler(ctx, conn, c.idgen, c.services) @@ -165,6 +166,7 @@ func Dial(rawurl string) (*Client, error) { // // The context is used to cancel or time out the initial connection establishment. It does // not affect subsequent interactions with the client. +// minhdoan: Dial with context and different rpc types. func DialContext(ctx context.Context, rawurl string) (*Client, error) { u, err := url.Parse(rawurl) if err != nil { @@ -518,6 +520,7 @@ func (c *Client) reconnect(ctx context.Context) error { // dispatch is the main loop of the client. // It sends read messages to waiting calls to Call and BatchCall // and subscription notifications to registered subscriptions. +// minhdoan: main loop of client. func (c *Client) dispatch(codec ServerCodec) { var ( lastOp *requestOp // tracks last send operation diff --git a/rpc/handler.go b/rpc/handler.go index 92db89e2f8..d8263b3179 100644 --- a/rpc/handler.go +++ b/rpc/handler.go @@ -71,6 +71,7 @@ type callProc struct { notifiers []*Notifier } +// minhdoan: RPC handler func newHandler(connCtx context.Context, conn jsonWriter, idgen func() ID, reg *serviceRegistry) *handler { rootCtx, cancelRoot := context.WithCancel(connCtx) h := &handler{ @@ -93,6 +94,7 @@ func newHandler(connCtx context.Context, conn jsonWriter, idgen func() ID, reg * } // handleBatch executes all messages in a batch and returns the responses. +// minhdoan: handle a list of rpc messages. func (h *handler) handleBatch(msgs []*jsonrpcMessage) { // Emit error response for empty batches: if len(msgs) == 0 { @@ -131,6 +133,7 @@ func (h *handler) handleBatch(msgs []*jsonrpcMessage) { } // handleMsg handles a single message. +// minhdoan: handle a single rpc json message. func (h *handler) handleMsg(msg *jsonrpcMessage) { if ok := h.handleImmediate(msg); ok { return diff --git a/rpc/json.go b/rpc/json.go index b2e8c7bab3..74ef28b02a 100644 --- a/rpc/json.go +++ b/rpc/json.go @@ -170,6 +170,7 @@ type jsonCodec struct { // NewCodec creates a new RPC server codec with support for JSON-RPC 2.0 based // on explicitly given encoding and decoding methods. +// minhdoan: this is where codec is generated by all rpc types func NewCodec(conn Conn, encode, decode func(v interface{}) error) ServerCodec { codec := &jsonCodec{ closed: make(chan interface{}), @@ -184,6 +185,7 @@ func NewCodec(conn Conn, encode, decode func(v interface{}) error) ServerCodec { } // NewJSONCodec creates a new RPC server codec with support for JSON-RPC 2.0. +// minhdoan: this is where codec is generated by all rpc types func NewJSONCodec(conn Conn) ServerCodec { enc := json.NewEncoder(conn) dec := json.NewDecoder(conn)